Capitolul 5

Procesarea caracterelor

5.1 Tipul de data "char"

Este unul dintre tipurile fundamentale din limbajul C. Constantele si variabilele de acest tip sunt folosite pentru reprezentarea caracterelor. Fiecare caracter este memorat pe 1 byte (octet), care (in general) este compus din 8 biti. Un octet compus din 8 biti poate pastra 2^8=256 valori distincte.
Cand memoram un caracter intr-un octet, continutul acestuia poate fi gandit ca un caracter sau un intreg mic (intre 0 si 255). Desi putem memora 256 valori distincte, doar o parte din ele sunt tiparibile (litere mici, mari, cifre, semne de punctuatie, spatiu, tab, caractere speciale +, *, %). Exemple de caractere netiparibile: newline, bell.
O constanta caracter se scrie intre apostroafe, cum ar fi: 'a', 'b'. O declaratie obisnuita a unei variabile de tip caracter este:
char c;
Variabilele caracter se pot initializa astfel:
char c1 = 'A', c2 = '*';
Un caracter este pastrat in memorie pe un octet dupa o codificare specifica. Multe masini folosesc codurile de caractere ASCII sau EBCDIC. Ne vom referi numai la codul ASCII. Astfel, vom preciza constanta caracter si valoarea corespunzatoare a sa:
- de la 2^5+2^4 pana la 57, in ordine: '0', '1', ..., '9'
- de la 2^6+2^0 pana la 90, in ordine: 'A', 'B', ..., 'Z'
- de la 2^6+2^5+2^0 pana la 112, in ordine: 'a', 'b', ..., 'z'

De exemplu, se observa ca pentru a obtine litere mici din cele mari, schimbam doar un bit. Astfel, caracterul 'A' are codul 65 care inseamna numarul 01000001 in baza 2, iar caracterul 'a' are codul 01100001. Se observa ca difera doar bitul cu numarul 3.

Exemple:

In functiile "printf()" si "scanf()", pentru formatul caracter se foloseste %c.
- printf("%c", 'a'); va tipari a
- printf("%c%c%c", 'A', 'B', 'C'); va tipari ABC
- printf("%d", 'a'); va tipari 97
- printf("%c", 97); va tipari a

Anumite caractere netiparibile necesita "secvente escape" (\ reprezinta caracterul escape). In acest sens, cream un tabel:

Numele caracterului
Modul de scriere
Valoarea intreaga
alert
\a
7
backslash
\\
92
backspace
\b
8
carriage return
\r
13
ghilimea
\"
34
formfeed
\f
12
tab orizontal
\t
9
newline
\n
10
caracterul nul
\0
0
apostrof
\'
39
tab vertical
\v
11

Exemple: Ce va fi afisat in cazul urmatoarelor instructiuni ?

1. printf("\"ABC\"");
2. printf("'ABC'");

Un alt mod de a scrie o constanta caracter este folosind una, doua sau trei cifre octale ca secvente escape, cum ar fi '\007'. Acest '\007' este de fapt caracterul "alert" (sau clopotel). El mai poate fi scris '\07' sau '\7' sau \a.

5.2 Utilizarea lui "getchar()" si "putchar()"

Aceste functii sunt folosite pentru citirea si scrierea caracterelor si sunt definite in . Astfel pentru citirea unui caracter de la tastatura se foloseste "getchar()", iar pentru scrierea unui caracter pe ecran "putchar()".
Bineinteles ca daca dorim sa afisam un sir de caractere mai mare, este mai elegant cu functia "printf()".

Exemplu:

Urmatorul program citeste un caracter din intrare (tastatura) si il atribuie unei varibile de tip char, apoi il afiseaza pe ecran.
#include
main()
{
char c;

while (1)
{
c=getchar();
putchar(c);
}
}

Singurul mod de a opri acest program este sa apasam CTRL^C. Putem reface acest program folosind constanta EOF.
#include
main()
{
int c;

while ((c = getchar()) != EOF)
{
putchar(c);
}
}


Comentarii:

1. In biblioteca , exista o linie in care se declara #define EOF (-1). Denumirea lui EOF provine de la "end-of-file".
2. Variabila c trebuie sa fie declarata de tip int si nu de tip char. Am vazut ca sfarsitul unui fisier este codificat cu -1, si nu cu un caracter.
3. Subexpresia c=getchar() citeste o valoare de la tastatura si o asigneaza variabilei c
.

5.3 Biblioteca

Sistemul C pune la dispozitie fisierul header care contine o multime de macro-uri (definitii) folosite pentru testarea
caracterelor si o multime de prototipuri de functii ce sunt folosite pentru conversia caracterelor.
In tabelul de mai jos prezentam o lista de macro-uri folosite la testarea caracterelor. Aceste macro-uri iau ca argument o variabila de tip int si returneaza o valoare de tip int (zero=false, diferit de zero=true).

Macro
Se returneaza true (diferit de zero) daca
isalpha(c)
c este litera
isupper(c)
c este litera majuscula
islower(c)
c este litera mica
isdigit(c)
c este cifra
isalnum(c)
c este litera sau cifra
isxdigit(c)
c este cifra hexazecimala
isspace(c)
c este caracter spatiu
ispunct(c)
c este semn de punctuatie
isprint(c)
c este caracter tiparibil
isgraph(c)
c este tiparibil, dar diferit de spatiu
iscntrl(c)
c este caracter de control
isascii(c) c
este cod ASCII

In tabelul urmator, vom scrie functiile "toupper()" si "tolower()", care sunt din biblioteca standard si macro-ul "toascii()". Macro-ul si prototipurile pentru cele doua functii sunt in . Acestea au ca argument o variabila de tip int si returneaza tipul int.
- toupper(c) schimba c din litera mica in majuscula
- tolower(c) schimba c din majuscula in litera mica
- toascii(c) schimba c cu codul ASCII

5.4 Un exemplu (util): Numararea cuvintelor

Vrem sa numaram cate cuvinte sunt introduse de la tastatura. Ele sunt separate prin spatiu. Pentru scrierea programului vom utiliza tot strategia "top-down".
#include
#include
main()
{
int numar_cuvinte = 0;
int gaseste_urmatorul_cuvant(void);

while (gaseste_urmatorul_cuvant() == 1)
++ numar_cuvinte;
printf("Numarul de cuvinte = %d\n\n", numar_cuvinte);
}

int gaseste_urmatorul_cuvant(void)
{
int c;

while (isspace(c = getchar()))
; /* sarim peste spatii */
if (c != EOF)
{
while ((c = getchar()) != EOF && !isspace(c))
; /* sarim peste orice diferit de EOF si spatii */
if (c != EOF) return 1;
else return 0;
}
return 0;
}