Sunteți pe pagina 1din 9

Valeriu Iorga Programare n C / C++

8.7. iruri de caractere.


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!" "#
)

S-ar putea să vă placă și