Extras din curs
Functii de intrare / iesire relative la siruri de caractere.
Pentru a citi un sir de caractere de la intrarea standard se foloseste functia gets() având prototipul:
char *gets(char *s);
Functia gets() citeste caractere din fluxul standard de intrare stdin în zona de memorie adresata de pointerul s. Citirea continua pâna la întâlnirea sfârsitului de linie. Marcajul de sfârsit de linie nu este copiat, în locul lui fiind pus caracterul nul (’�’). Functia întoarce adresa zonei de memorie în care se face citirea (adica s) sau NULL, daca în locul sirului de caractere a fost introdus marcajul de sfârsit de fisier.
Pentru a scrie un sir de caractere terminat prin caracterul NULL, la iesirea standard stdout, se foloseste functia:
int puts(char *s);
Caracterul terminator nu este transmis la iesire, în locul lui punându-se marcajul de sfârsit de linie.
Caracterele citite într-un tablou ca un sir de caractere (cu gets()) pot fi convertite sub controlul unui format folosind functia:
int sscanf(char *sir, char *format, adrese_var_formatate);
Singura deosebire fata de functia scanf() consta în faptul ca datele sunt preluate dintr-o zona de memorie, adresata de primul parametru (si nu de la intrarea standard).
Exemplul 26: Scrieti o functie care citeste cel mult n numere reale, pe care le plaseaza într-un tablou x. Functia întoarce numarul de valori citite.
Vom citi numerele într-un sir de caractere s. De aici vom extrage în mod repetat câte un numar, folosind functia sscanf() si îl vom converti folosind un format corespunzator. Ciclul se va repeta de n ori, sau se va opri când se constata ca s-au terminat numerele.
Vom scrie functia în 2 variante: folosind tablouri sau folosind pointeri.
/* varianta cu tablouri */
int citreal(int n, double x[])
{ char s[255];
int j;
double y;
for (j=0; j<n; j++) {
if(gets(s)==NULL)
return j;
if(sscanf(s,”%lf”,&y)!=1) /*conversie ]n real*/
break; /*s-au terminat numerele*/
x[j]=y;
}
return j;
}
/* varianta cu pointeri */
int citreal(int n, double *px)
{ char s[255];
int j=0;
double y;
double *p=px+n;
while(px<p) {
if(gets(s)==NULL)
return j;
if(sscanf(s,”%lf”,&y)!=1) /*conversie in real*/
break; /*s-au terminat numerele*/
*px++=y;
j++;
}
return j;
}
Tablouri de pointeri.
Un tablou de pointeri este definit prin:
tip *nume[dimensiune];
Exemplul 27: Sa se sorteze o lista de nume.
Folosirea unui tablou de siruri de caractere este lipsita de eficienta, deoarece sirurile sunt de lungimi diferite. Vom folosi un tablou de pointeri la siruri de caractere.
Prin sortare nu se vor schimba sirurile de caractere, ci pointerii catre acestea.
Citirea sirurilor de caractere presupune:
• rezervarea de spatiu pentru siruri
• initializarea tabloului de pointeri cu adresele sirurilor
Pentru rezervarea de spatiu se foloseste functia char *strdup(char *s);
care:
• salveaza sirul indicat de s într-o zona de memorie disponibila, alocata dinamic
• întoarce un pointer catre zona respectiva sau NULL.
Citirea numelor este terminata prin EOF. Functia de citire întoarce numarul de linii citite:
int citire(char *tabp[]){
int j=0;
char tab[80];
while(1) {
gets(tab);
if(tab==NULL)
break;
tabp[j]=strdup(tab);
}
return j;
}
Sortarea o vom realiza cu algoritmul bulelor: daca sirul de nume ar fi ordonat, atunci doua nume consecutive s-ar afla în relatia < sau ==. Vom cauta asadar relatiile >, schimbând de fiecare data între ei pointerii corespunzatori (schimbare mai eficienta decât schimbarea sirurilor). Se fac mai multe parcurgeri ale listei de nume; la fiecare trecere, o variabila martor – sortat, initializata la 1 este pusa pe 0, atunci când se interschimba doi pointeri. Lista de nume va fi sortata în momentul în care în urma unei parcurgeri a listei se constata ca nu s-a mai facut nici o schimbare de pointeri.
void sortare(char *tp[], int n) {
int j, sortat;
char *temp;
for(sortat=0; !sortat;){
sortat=1;
for(j=0;j<n-1;j++)
if(strcmp(tp[j],tp[j+1])>0){
temp=tp[j],
tp[j]=tp[j+1],
tp[j+1]=temp,
sortat=0;
}
}
}
void afisare(char *tp[], int n){
int j;
for (j=0; j<n; j++)
if(tp[j])
puts(tp[j]);
}
void main(void)
{ int n;
char *nume[100];
n=citire(nume);
sortare(nume,n);
afisare(nume,n);
}
Preview document
Conținut arhivă zip
- Siruri de caractere in C si C++.doc