O constant ir de caractere se reprezint intern printr-un tablou de caractere terminat prin caracterul nul \0, memoria alocat fiind lungimea irului + ! octet pentru caracterul terminator al irului "# $n tablou de caractere poate fi ini%ializat fr a-i specifica dimensiunea& char salut[]={B,o,n,j,o,u,r,!,\0}; sau mai simplu, specific'nd irul ntre g(ilimele& char salut[]=Bonjour! !tabloul este ini%ializat cu con%inutul irului de caractere -se aloc ) octe%i" *olosirea unui pointer la un ir de caractere ini%ializat nu copiaz irul, ci are urmtorul efect& se aloc memorie pentru irul de caractere, inclusi+ terminatorul nul la o adres fi, de memorie se ini%ializeaz spa%iul cu +alorile constantelor caractere se ini%ializeaz pointerul Psalut cu adresa spa%iului alocat char *Psalut=Buna ziua!; !pointerul este ini%ializat s indice o constant ir de caractere" -adar, n C nu exist operaia de atribuire de iruri de caractere !sau n general de atribuire de tablouri", ci numai atribuire de pointeri - atribuirea t=s nu copiaz un tablou, pentru aceasta se folosete func%ia strcp!t, s". Pentru a uura lucrul cu iruri de caractere, n biblioteca standard sunt pre+zute o serie de func%ii, ale cror prototipuri sunt date n fiierele #ctp$%h& i #strin'%h&. .n fiierul <ctp$%h& e,ist o serie de func%ii !codificate ca macroinstruc%iuni" care primesc un parametru ntreg, care se con+ertete n unsi'n$( char, i ntorc rezultatul diferit de / sau egal cu /, dup cum caracterul argument satisface sau nu condi%ia specificat& islo)$r!c" * (ac+ c {a%%z} isupp$r!c" * (ac+ c {,%%-} isalpha!c" * (ac+ c {,%%-}{a%%z} is(i'it!c" * (ac+ c {0%%.} is/(i'it!c" * (ac+ c {0%%.}{,%%0}{a%%1} isalnu2!c" * (ac+ isalpha!c"33is(i'it!c" isspac$!c" * (ac+ c { ,\n,\t,\r,\1,\4} is'raph!c" * (ac+ c $st$ a1i5a6il, 1+r+ spa7iu isprint!c" * (ac+ c $st$ a1i5a6il, cu spa7iu iscntrl!c" * (ac+ c $st$ caract$r ($ control ispunct!c" * (ac+ is'raph!c" 88 !isalnu2!c" Con+ersia din liter mare n liter mic i in+ers se face folosind func%iile& tolo)$r!c" i toupp$r!c". 0,emplul ): Scriei o funcie care convertete un ir de caractere reprezentnd un numr ntreg, ntr-o valoare ntreag. umrul poate avea semn i poate fi precedat de spaii albe. 9inclu($ #ctp$%h& int atoi!char *s" { int i, nr, s$2n; 1or!i=0; isspac$!s[i]"; i::" ;*i'nora spatii al6$*; ; s$2n=!s[i]==<*"=<*>*; ;*sta6ilir$ s$2n*; i1!s[i]==:33s[i]==<" ;*s$ sar$ s$2nul*; i::;
Valeriu Iorga Programare n C / C++
1or!nr=0;is(i'it!s[i]";i::" ;*con4$rsi$ in ci1ra*; nr=*0*nr:!s[i]<0"; ;*si alipir$ la nu2ar*; r$turn s$2n*nr; } 0,emplul 1/& Scriei o funcie care convertete un ntreg ntr-un ir de caractere n baza !". -lgoritmul cuprinde urmtorii pai& { s$ $/tra'$ s$2nul nu2+rului; s$ $/tra' ci1r$l$ nu2+rului, ?nc$p@n( cu c2ps; s$ trans1or2+ ?n caract$r$ 5i s$ ($pun ?ntr<un ta6lou; s$ a(au'+ s$2nul 5i t$r2inatorul ($ 5ir; s$ in4$rs$az+ 5irul; } 4oi( in4$rsar$!char[]"; 4oi( itoa!int n, char s[]"{ int j, s$2n; i1!!s$2n=n"#0" n=<n; j=0; (o s[j::]=nA*0:0; )hil$ !!n;=*0"&0"; i1!s$2n#0" s[j::]=<; s[j]=\0; in4$rsar$!s"; } 4oi( in4$rsar$!char s[]" { int i,j; char c; 1or!i=0,j=strl$n!s"<*;i#j;i::,j<<" c=s[i], s[i]=s[j], s[j]=c; } 0,emplul 1: Scriei o funcie care convertete un ntreg fr semn ntr-un ir de caractere n baza !#. Pentru a trece cu uurin% de la +alorile cifrelor (e,azecimale 0,*,B*C la caracterele corespunztoare2 0,*,B,a,B,1, +om utiliza un tablou ini%ializat de caractere# static char h$/a[]=0*DEFCGHI.a6c($1; 4oi( itoh!int n, char s[]" { j=0; (o { s[j::]=h$/a[nA*G]; )hil$ !!n;=*G"&0"; s[j]=\0; in4$rsar$!s"; } *iierul #strin'%h& con%ine prototipurile urmtoarelor func%ii& char* strcp!char* (,const char* s" copiaz irul s n (, inclusi+ \0, ntoarce ( char* strncp!char* (,const char* s, int n" copiaz n caractere din irul s n (, complet'nd e+entual cu \0, ntoarce ( char* strcat!char* (,const char* s" concateneaz irul s la sf'ritul lui (, 1 Valeriu Iorga Programare n C / C++ ntoarce ( char* strncat!char* (,const char* s, int n" concateneaz cel mult n caractere din irul s la sf'ritul lui (, complet'nd cu \0, ntoarce ( int strc2p!const char* (, const char* s" compar irurile ( i s, ntoarce J* dac (#s, 0 dac (==s i * dac (&s int stric2p!const char* (, const char* s" compar irurile ( i s !ca i strc2p!"" fr a face distinc%ie ntre litere mari i mici int strnc2p!const char* (, const char* s, int n " similar cu strc2p!", cu deosebirea c se compar cel mult n caractere int strinc2p!const char* (, const char* s, int n " similar cu strnc2p!", cu deosebirea c nu se face distinc%ie ntre literele mari i mici char* strchr!const char* (,char c" caut caracterul c n irul (; ntoarce un pointer la prima apari%ie a lui c n (, sau KLMM char* strrchr!const char* (,char c" ntoarce un pointer la ultima apari%ie a lui c n (, sau KLMM char* strstr!const char* (, const char* s" ntoarce un pointer la prima apari%ie a subirului s n (, sau KLMM char* strp6rN!const char* (, const char* s" ntoarce un pointer la prima apari%ie a unui caracter din subirul s n (, sau KLMM int strspn!const char* (, const char* s" ntoarce lungimea prefi,ului din ( care con%ine numai caractere din s int strcspn!const char* (, const char* s" ntoarce lungimea prefi,ului din ( care con%ine numai caractere ce nu apar n s int strl$n!const char* s" ntoarce lungimea lui s !\0 nu se numr) char* strl)r!char* s" con+ertete literele mari n litere mici n s char* strupr!char* s" con+ertete literele mici n litere mari n s 4oi(* 2$2cp!4oi(* (, const 4oi(* s,int n" copiaza n octe%i din s n (2 ntoarce ( 4oi(* 2$22o4$!4oi(* (, const 4oi(* s,int n" ca i 2$2cop, folosit daca s i ( se ntreptrund 4oi(* 2$2s$t!4oi(* (,const int c, int n" copiaz caracter c n primele n pozi%ii din ( int 2$2c2p!const 4oi(* (, const 4oi(* s,int n" compar zonele adresate de s i ( char* strtoN!const char* (, const char* s" caut n ( subirurile delimitate de caracterele din s;primul apel ntoarce un pointer la primul subir din ( care nu con%ine caractere din s urmtoarele apeluri se fac cu primul argument KLMM, ntorc'ndu-se de fiecare dat un pointer la urmtorul subir din ( ce nu con%ine caractere din s; n momentul n care nu mai e,ist subiruri, func%ia ntoarce KLMM Ca e,erci%iu, +om codifica unele din func%iile a cror prototipuri se gsesc n #strin'%h&, scriindu-le n dou +ariante& cu tablouri i cu pointeri. 0,emplul 11&Scriei o funcie avnd ca parametru un ir de caractere, care ntoarce lungimea sirului ;*4arianta cu ta6louri*; 3 Valeriu Iorga Programare n C / C++ int strl$n!char *s" { int j; 1or!j=0; *(!=\0; (::" j::; r$turn j; } ;*4arianta cu point$ri*; int strl$n!char *s" { char *p=s; )hil$!*p" p::; r$turn p<s; } 0,emplul 13&Scriei o funcie care copiaz un ir de caractere s n (. ;*4arianta cu ta6louri*; 4oi( strcp!char *(, char *s" { int j=0; )hil$!!([j]=s[j]"!=\0" j::; } ;*4arianta cu point$ri*; 4oi( strcp!char *(, char *s" { )hil$!!*(=*s"!=\0"{ (::; s::; } Postincrementarea pointerilor poate fi fcut n opera%ia de atribuire deci& 4oi( strcp!char *(, char *s"{ )hil$!!*(::=*s::"!=\0" ; } 4estul fa% de \0 din )hil$ este redundant, deci putem scrie: 4oi( strcp!char *(, char *s"{ )hil$!*(::=*s::" ; } 0,emplul 15& Scriei o funcie care compar lexicografic dou iruri de caractere i ntoarce rezultatul J*, 0 sau * dup cum (#s, (==s sau (&s. ;*4arianta cu ta6louri*; int strc2p!char *(, char *s" { int j; 1or!j=0; ([j]==s[j]; j::" i1!([j]==\0" r$turn 0; r$turn ([j]<s[j]; } ;*4arianta cu point$ri*; int strc2p!char *(, char *s" { 1or!; *(==*s; (::,s::" 5 Valeriu Iorga Programare n C / C++ i1!*(==\0" r$turn 0; r$turn *(<*s; } 0,emplul 16& Scriei o funcie care determin poziia $indexul% primei apariii a unui subir s ntr-un ir (. &ac s nu apare n (, funcia ntoarce J*. int strin(!char ([], char s[]"{ int i,j,N; 1or !i=0; ([i]; i::" { 1or !j=i,N=0; s[N] 88 ([j]==s[N]; j::,N::" ; i1 !N&0 88 s[N]==\0" r$turn i; } r$turn J*; } 8.8. Funcii de intrare / ieire relative la iruri de caractere. Pentru a citi un ir de caractere de la intrarea standard se folosete func%ia '$ts!" a+'nd prototipul: char *'$ts!char *s"; *unc%ia '$ts!" citete caractere din flu,ul standard de intrare st(in n zona de memorie adresat de pointerul s. Citirea continu p'n la nt'lnirea sf'ritului de linie# 7arca8ul de sf'rit de linie nu este copiat, n locul lui fiind pus caracterul nul (\0). *unc%ia ntoarce adresa zonei de memorie n care se face citirea !adic s) sau KLMM, dac n locul irului de caractere a fost introdus marca8ul de sf'rit de fiier# Pentru a scrie un ir de caractere terminat prin caracterul KLMM, la ieirea standard st(out, se folosete func%ia: int puts!char *s"; Caracterul terminator nu este transmis la ieire, n locul lui pun'ndu-se marca8ul de sf'rit de linie# Caracterele citite ntr-un tablou ca un ir de caractere !cu '$ts!") pot fi con+ertite sub controlul unui format folosind func%ia& int sscan1!char *sir, char *1or2at, a(r$s$O4arO1or2atat$"; 9ingura deosebire fa% de func%ia scan1!" const n faptul c datele sunt preluate dintr-o zon de memorie, adresat de primul parametru !i nu de la intrarea standard"# 0,emplul 1:& Scriei o funcie care citete cel mult n numere reale, pe care le plaseaz ntr-un tablou /. 'uncia ntoarce numrul de valori citite. Vom citi numerele ntr-un ir de caractere s. ;e aici +om e,trage n mod repetat c'te un numr, folosind func%ia sscan1!" i l +om con+erti folosind un format corespunztor# Ciclul se +a repeta de n ori, sau se +a opri c'nd se constat c s-au terminat numerele# Vom scrie func%ia n 1 +ariante& folosind tablouri sau folosind pointeri. ;* 4arianta cu ta6louri *; int citr$al!int n, (ou6l$ /[]" { char s[DCC]; int j; (ou6l$ ; 1or !j=0; j#n; j::" { i1!'$ts!s"==KLMM" 6 Valeriu Iorga Programare n C / C++ r$turn j; i1!sscan1!s,Al1,8"!=*" ;*con4$rsi$ ]n r$al*; 6r$aN; ;*s<au t$r2inat nu2$r$l$*; /[j]=; } r$turn j; } ;* 4arianta cu point$ri *; int citr$al!int n, (ou6l$ *p/" { char s[DCC]; int j=0; (ou6l$ ; (ou6l$ *p=p/:n; )hil$!p/#p" { i1!'$ts!s"==KLMM" r$turn j; i1!sscan1!s,Al1,8"!=*" ;*con4$rsi$ in r$al*; 6r$aN; ;*s<au t$r2inat nu2$r$l$*; *p/::=; j::; } r$turn j; } 8.9. Tablouri de pointeri. $n tablou de pointeri este definit prin& tip *nu2$[(i2$nsiun$]; Exemplul 27: S se sorteze o list de nume. *olosirea unui tablou de iruri de caractere este lipsit de eficien%, deoarece irurile sunt de lungimi diferite# Vom folosi un tablou de pointeri la iruri de caractere# Prin sortare nu se +or sc(imba irurile de caractere, ci pointerii ctre acestea# Citirea irurilor de caractere presupune& rezer+area de spa%iu pentru iruri ini%ializarea tabloului de pointeri cu adresele irurilor Pentru rezer+area de spa%iu se folosete func%ia char *str(up!char *s"; care& sal+eaz irul indicat de s ntr-o zon de memorie disponibil, alocat dinamic ntoarce un pointer ctre zona respecti+ sau KLMM. Citirea numelor este terminat prin PQ0. *unc%ia de citire ntoarce numrul de linii citite& int citir$!char *ta6p[]"{ int j=0; char ta6[I0]; )hil$!*" { : Vasile Constantin Ion Vasile Constantin Ion Valeriu Iorga Programare n C / C++ '$ts!ta6"; i1!ta6==KLMM" 6r$aN; ta6p[j]=str(up!ta6"; } r$turn j; } 9ortarea o +om realiza cu algoritmul bulelor& dac irul de nume ar fi ordonat, atunci dou nume consecuti+e s-ar afla n rela%ia # sau ==# Vom cuta aadar rela%iile &, sc(imb'nd de fiecare dat ntre ei pointerii corespunztori !sc(imbare mai eficient dec't sc(imbarea irurilor"# 9e fac mai multe parcurgeri ale listei de nume2 la fiecare trecere, o +ariabil martor < sortat, ini%ializat la este pus pe /, atunci c'nd se intersc(imb doi pointeri# =ista de nume +a fi sortat n momentul n care n urma unei parcurgeri a listei se constat c nu s-a mai fcut nici o sc(imbare de pointeri# 4oi( sortar$!char *tp[], int n" { int j, sortat; char *t$2p; 1or!sortat=0; !sortat;"{ sortat=*; 1or!j=0;j#n<*;j::" i1!strc2p!tp[j],tp[j:*]"&0"{ t$2p=tp[j], tp[j]=tp[j:*], tp[j:*]=t$2p, sortat=0; } } } 4oi( a1isar$!char *tp[], int n"{ int j; 1or !j=0; j#n; j::" i1!tp[j]" puts!tp[j]"; } 4oi( 2ain!4oi(" { int n; char *nu2$[*00]; n=citir$!nu2$"; sortar$!nu2$,n"; a1isar$!nu2$,n"; } 0,emplul 1> & &efinii o funcie, avnd ca parametru un ntreg, reprezentnd o lun, care ntoarce $un pointer la% numele acelei luni char *nu2$Oluna!int n" { static char *nu2$[]={RMuna in$/ist$nta,Sanuari$, R0$6ruari$,Tarti$,,prili$,RTai,Suni$, Suli$,,u'ust,RU$pt$26ri$,Qcto26ri$, RKoi$26ri$,V$c$26ri$}; r$turn!n#*33n&*D"=nu2$[0]>nu2$[n]; } 8.10. Probleme propuse (iruri de caractere. ? Valeriu Iorga Programare n C / C++ # 9crie%i o func%ie C care stabilete dac un ir de caractere dat ca parametru reprezint un palindrom# Pentru aceasta este necesar ca primul i ultimul caracter din irul de caractere s fie egale, al doilea i penultimul, #a#m#d# *unc%ia ntoarce dac irul de caractere este un palindrom i / n caz contrar# 1# $n te,t citit de pe mediul de intrare reprezint un program C# 9 se copieze pe mediul de ieire, pstr'nd structura liniilor, dar suprim'nd toate comentariile# 3# ;intr-un te,t, citit de pe mediul de intrare, s se separe toate cu+intele, plas'ndu-le ntr-un +ector cu elemente iruri de caractere de lungime / !cu+intele mai scurte se +or completa cu spa%ii libere, iar cele mai lungi se +or trunc(ia la primele / caractere# 9e +or afia elemenetele acestui tablou, c'te 6 elemente pe o linie, separate ntre ele prin 1 asteriscuri# 5# ;intr-un te,t citit de pe mediul de intrare s se afieze toate cu+intele care con%in cel pu%in 3 +ocale distincte# 6# 9crie%i un program care citete i afieaz un te,t i determin numrul de propozi%ii i de cu+inte din te,t# *iecare propozi%ie se termin prin punct, iar n interiorul propozi%iei cu+intele sunt separate prin spa%ii, +irgul sau liniu%# :# ;e pe mediul de intrare se citete un te,t format din cu+inte separate prin spa%ii libere# 9 se afieze acest te,t la ieire, pstr'nd structura liniilor i scriind n dreptul liniei cel mai lung cu+'nt din linie# ;ac mai multe cu+inte au aceeai lungime ma,im, +a fi afiat numai primul dintre ele# ?# 9crie%i un program care citete de la intrarea standard cu+inte, p'n la nt'lnirea caracterului punct i afieaz c'te un cu+'nt pe o linie, urmat de despr%irea acestuia n silabe# 9e utilizeaz urmtoarele reguli de despr%ire n silabe& o consoan aflat ntre dou +ocale trece n silaba a doua n cazul a dou sau mai multe consoane aflate ntre dou +ocale, prima rm'ne n silaba nt'ia, iar celelalte trec n silaba urmtoare# @u se iau n considerare e,cep%iile de la aceste reguli# ># 9 se transcrie la ieire un te,t citit de la intrarea standard, suprim'nd toate cu+intele de lungime mai mare ca /# Cu+intele pot fi separate prin punct, +irgul sau spa%ii libere i nu se pot continua de pe o linie pe alta# )# 9crie%i un program care citete de la intrarea standard un te,t terminat prin punct i l transcrie la ieirea standard, nlocuind fiecare caracter * printr-un numr corespunztor de spa%ii libere care ne pozi%ioneaz la urmtoarea coloan multiplu de 6# 9e +a pastra structura de linii a te,tului# /# 9crie%i un program pentru punerea n pagin a unui te,t citit de la intrarea standard# 9e fac urmtoarele precizri& cu+intele sunt separate ntre ele prin cel pu%in un spa%iu un cu+'nt nu se poate continua de pe o linie pe alta lungimea liniei la ieire este N lungimea ma,im a unui cu+'nt este mai mic dec't K ; D In te,tul rezultat se cere ca la nceput de linie s fie un nceput de cu+'nt, iar sf'ritul de linie s coincid cu sf'ritul de cu+'nt# .n acest scop, spa%iile se distribuie uniform i simetric ntre cu+inte# *ace e,cep%ie doar ultima linie# Caracterul punct apare doar la sf'rit de te,t# > Valeriu Iorga Programare n C / C++ # 7odifica%i func%ia strin(!" astfel nc't s ntoarc n locul inde,ului un pointer i KLMM n caz c c subirul s nu apare n irul destina%ie ( !adic scrie%i func%ia strstr!" "# )