Cum programezi cu siruri de caractere in limbajul C
Calculatorul a fost conceput initial ca sa permita efectuarea automata de calcule. Si chiar asta face el in realitate. Face operatii cu numere. (Caci da — textele, imaginile, sunetele sunt toate stocate in calculator ca niste numere.
Doar ca omului ii este dificil sa opereze cu numere. Omul e, in schimb, obisnuit sa vorbeasca si sa asculte. Si, ceva mai tarziu la scara istoriei, s-a obisnuit sa scrie si sa citeasca.
Asa s-a ajuns ca astazi omului sa ii fie foarte usor sa lucreze cu texte. Cu siruri de litere si alte simboluri, adica. (Chiar si programele pe care le scriem in C (sau in alte limbaje de programare) sunt astfel de “texte”.)
Asta e motivul pentru care orice limbaj de programare serios permite facilitati pentru efectuarea de operatii asupra textelor. Adica a “sirurilor de caractere” — cum sunt ele denumite in programare.
Caractere in C
Am mai vorbit despre siruri de caractere in Abecedar si ti-am spus ca literele, cifrele si simbolurile sunt stocate in calculator sub forma de valori numerice.
In limbajul C caracterele (adica literele sau simbolurile grafice ce pot aparea intr-un text) sunt reprezentate ca numere pe 8 biti, conform codului ASCII, tipul de date pentru astfel de valori fiind char. Ca sa simplifice munca programatorului, compilatorul de C intelege ca o litera (sau simbol) plasata intre apostrofuri reprezinta, de fapt, numarul corespunzator ei in codul ASCII.
Adica urmatoarele doua variabile au aceeasi valoare:
...
char a_1 = 97;
char a_2 = 'a';
...
Aceste simboluri plasate intre apostrofuri pot fi folosite in limbajul C cam oriunde poti folosi valorile numerice corespunzatoare lor. Adica poti face operatii cu ele, de genul ‘a’+’b’ (care, apropo, este egal cu 97+98, adica 195). Ceea ce inseamna ca poti obtine rapid valoarea cifrei reprezentate de un caracter salvat in variabila c scriind in program c-‘0’. (Daca in c se gaseste un caracter din multimea {‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’}, rezultatul expresiei anterioare va fi un numar intre 0 si 9 — caci codurile ASCII corespunzatoare acestor cifre au valori succesive.)
Cam asta e cu caracterele, deci.
Dar cum e cu sirurile de caractere (sau strings, in engleza)?
Siruri de caractere in C
La fel cum e cu sirurile de numere. Da — la fel cum pentru siruri de numere putem folosi vectori, si pentru siruri de caracgere putem folosi vectori. Vectori de valori de tip char, mai precis.
In C nu exista un tip de date special pentru sirurile de caractere, ci se folosesc pentru acestea tipurile char[] sau char *. (Ti-am explicat in lectia despre pointeri care e legatura dintre vectori si pointeri in C.)
Fata de un vector obisnuit, un sir de caractere in C are particularitatea ca trebuie sa se termine neaparat cu un element cu valoarea 0. (Bineinteles ca putem renunta la acel element si sa folosim in schimb o variabila in care stocam numarul de caractere din sir, dar in varianta asta nu putem beneficia de functiile pe care limbajul C ni le pune la dispozitie pentru lucrul cu sirurile de caractere.)
Exemplu de program cu string-uri in C
Ca sa nu lungesc prea mult explicatiile, incerc sa fac in continuare un program in care sa includ cele mai uzuale operatii cu sirurile de caractere in C:
#include <stdio.h>
#include <string.h>
void main()
{
char nume[10] = "Florin"; // ={'F','l','o','r','i','n',0}
char salut[] = "Salut, ";
char salut_nume[21];
if (strlen(salut)+strlen(nume)+strlen("!")+1 > 21)
{
printf("Spatiu insuficient in vectorul salut_nume!\n");
return; // Termina programul
}
// Daca nu s-a terminat programul, se executa astea:
strcpy(salut_nume, salut);
strcpy(salut_nume+strlen(salut_nume), nume);
strcpy(salut_nume+strlen(salut_nume), "!");
printf("%s\n", salut_nume);
}
In primul rand, a se observa ca vectorul {‘F’, ‘l’, ‘o’, ‘r’, ‘i’, ‘n’} poate fi scris simplificat asa: “Florin”. (E clar, deci, ca in limbajul C “!” (cu ghilimele) e ceva diferit de ‘!’ (cu apostrofuri), da? Evident, “!” (cu ghilimele cu tot) inseamna vectorul {‘!’, 0}. Adica cu ghilimele se noteaza vectori de caractere (ce contin inclusiv elementul cu valoarea 0 ce marcheaza capatul din dreapta al sirului).)
A se observa, de asemenea, ca in programul anterior nume e un vector ce cuprinde 10 elemente, cu toate ca doar primele 7 dintre ele sunt utilizate pentru a stoca sirul “Florin”.
Vectorul salut din program nu are specificat numarul de elemente, asa ca el va fi setat automat la atatea elemente cate sunt necesare pentru a incapea valoarea data la initializare — adica 8 elemente.
Prin if-ul din program am verificat (doar asa, ca sa iti exemplific functia strlen), ca in vectorul salut_nume am suficient spatiu cat sa imi incapa in el concatenarea dintre continuturile sirurilor salut, nume si “!” (plus zeroul final, desigur).
Apoi am concatenat (adica am “alipit” cele 3 siruri) cu functia strcpy. Primul ei parametru e un char *, adica adresa unui char. Ea va copia la acea adresa primul element de la adresa data in cel de-al doilea parametru, apoi se va muta cu o pozitie la dreapta si va repeta operatia asta. Pana cand? Pana cand sirul din dreapta ajunge la final. Adica dupa ce ajunge sa scrie in sirul din stanga primul 0 din sirul din dreapta.
Prin expresia salut_nume+strlen(salut_nume) am obtinut un pointer catre zeroul de la coada sirului de caractere curent din vectorul salut_nume. Asa ca cel de-al doilea apel al functiei strcpy nu suprascrie continutul scris in salut_nume de primul apel al lui strcpy, ci adauga continut la dreapta.
In sfarsit, %s-ul din apelul functiei printf ii zice ca urmeaza adresa unui sir de caractere ce se termina cu caracterul nul (adica valoarea 0). Si va afisa toate caracterele (cu exceptia ultimului) pe ecranul (in mod text al) consolei, incepand de la pozitia curenta a cursorului.
Citirea unui sir de caractere in C
Hai sa vedem si cum putem citi de la tastatura un sir de caractere:
#include <stdio.h>
#include <string.h>
void main()
{
char nume[10];
char salut[] = "Salut, ";
char salut_nume[21];
// Citesc numele de la tastatura
scanf("%9s", nume);
// Compun mesajul, scriindu-l in sirul salut_nume
sprintf(salut_nume, "%s%s%s", salut, nume, "!");
// Afisez mesajul
printf("%s\n", salut_nume);
}
Asa cum ai vazut, pentru a citi de la tastatura un sir de caractere in C am folosit tot functia scanf — aceeasi pe care am folosit-o si la citirea de numere. Doar ca aici am folosit specificatorul de format %s, care ii spune ca parametrul reprezinta o adresa de memorie unde sa scrie sirul de caractere citit.
Si ca sa evit riscul de a citi ma multe caractere decat incap in vectorul nume, i-am zis sa citeasca maxim 9 caractere (ca sa las loc in vector si pentru zeroul final, ce este adaugat automat).
Apoi am scris continutul dorit in vectorul salut_nume folosind functia sprintf — care functioneaza cam la fel ca printf, doar ca primul ei parametru este adresa unui spatiu de memorie unde va scrie continutul rezultat.
Gata si lectia despre programarea cu siruri de caractere in limbajul C. Daca ai trecut cu bine de lectiile anterioare din acest tutorial de C, e foarte probabil ca lectia asta nu ti-a pus probleme.
(Cred ca ai inceput de ceva vreme sa simti cum noile notiuni care vin se aseaza cu usurinta pe temelia formata din notiunile fundamentale.)
In orice caz, in invatarea programarii exercitiul e de baza, asa ca ai liber la experimentat. Si nu uita sa te distrezi in timp ce faci asta! 🙂
Alatura-te celor peste 8000 de oameni din armata noastra de creiere cu muschi si vei primi testul care iti va spune daca ai sau nu minte de programator.
In plus, vei fi mereu la curent cu tot ce pun la cale.
Cu drag,