>> Inapoi <<
========
Capitolul 5
========
==================
Procesarea caracterelor
==================
---------------------------
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, dam 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.
---------------------------------------------------
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.
--------------------------
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
----------------
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;
}
-----------------------------------------------
Exercitii propuse spre implementare
-----------------------------------------------
1. Folosind functiile "getchar()" si "putchar()", sa se scrie un program C care
transforma literele mici in litere mari. Incercati si o varianta de program
care foloseste functiile "islower()" si "toupper()".
2. Utilizand functiile "getchar()" si "putchar()" creati un program C care sa
copie un fisier in alt fisier (comanda voastra proprie de copiere). Utilizati
redirectarea ! De asemeni, precizati si cazul cand dorim sa copiem un fisier la
sfarsitul unui fisier existent.
3. Scrieti in C un analizor lexical care sa recunoasca cat mai multi atomi
lexicali din C. De exemplu, cuvintele rezervate (while, do, for, ...),
identificatori, operatori (relationali, logici, artimetici, ...) si eventual
alte structuri. Apoi, tipariti acelasi fisier de intrare cu exceptia spatiilor
multiple si a comentariilor.
4. Scrieti un program C care citeste caractere de la tastatura si le scrie la
ecran. Scrieti toate vocalele cu litere majuscule si consoanele cu litere mici.
Apoi, scrieti un program C care citeste caractere de la tastatura si sterge
vocalele din ele (afisand doar consoanele). (Acest mod de scriere era folosit
in scrisul hieroglific al Greciei Antice).
5. ("Pretty printing")
Scrieti un program C care are la intrare un fisier sursa C si il transforma
intr-un program C scris frumos (eventual in stilul Bell Laboratoires).