Sunteți pe pagina 1din 5

2.6. Operaþii de conversie a unui ºir de caractere – cifre într-o valoare numericã ºi invers.

Existã situaþii în care o înºiruire de caractere de tip cifrã conþine o informaþie numericã ce trebuie prelucratã
prin operaþii matematice.
Expresia numericã: 51+7-2*9, figura 2.8, în care 51, 7, 2 ºi 9 sunt constante întregi, trebuie evaluatã
pentru a se crea valoarea –6 cu care ar continua prelucrãrile mai departe în algoritm. Dacã expresia
respectivã este cititã ca datã comunicatã de utilizator, forma în care ea se va regãsi în datele de intrare
va fi forma ºirului de caractere corespunzãtoare cifrelor ºi semnelor de operaþii pe care le conþine.
caractere ‘5’ ’1’ ’+’ ’7’ ’-’ ’2’ ’*’ ’9’
cod ASCII 53 49 43 55 45 50 42 57 Figura 2.8

Pentru a fi calculatã expresia, însã, codurile ASCII ale cifrelor 5 ºi 1 vor trebui sã participe la crearea
numãrului întreg 51, iar din codul ASCII al cifrelor 7, 2 ºi 9 trebuie determinate numerele întregi 7, 2 ºi 9, valori
care vor fi reprezentate în memorie în baza 2 ºi cu acestea se vor face calculele matematice cerute.
În alte situaþii, cum este cea a afiºãrii unor valori numerice interne, trebuie
ca pe ecran sã se prezinte ºirul de caractere corespunzãtor numerelor. Aceastã ’1’ ’2’ NULL
situaþie este întâlnitã atât în mod implicit, în funcþionarea fluxului de ieºire, cout, 49 50 0
pentru valori numerice, cât ºi în mod explicit, în situaþia scrierii grafice într-un desen,
Figura 2.9
prin funcþiile outtext ºi outtextxy.
De exemplu, valoarea internã 000011002, care reprezintã numãrul natural 1210, trebuie scrisã pe ecran în
mod grafic la coordonatele (200,150) prin intermediul funcþiei outtextxy(200,150,sir). Variabila sir va
trebui pregãtitã cu conþinutul ASCII al valorii interne 122 , cum se prezintã în figura 2.9.
Transformarea din format ºir de caractere în format numeric intern a unei date ºi invers este o operaþie de
conversie a tipului de reprezentare.
Ea este o conversie mai complicatã decât cele realizate de operatorul cast, pus la dispoziþie de limbaj.
Astfel, dacã se poate scrie:
float a= (float)1/2;
pentru a se realiza conversia valorii 1 din tipul întreg în tipul real ºi astfel calculul sã dea 0.5 nu 0, nu la fel se
poate scrie:
int a= char (12);
Biblioteca stdlib, pune la dispoziþie funcþii pentru conversii de acest tip. Modul de transformare este foarte
uºor de recunoscut dupã numele funcþiei care este un acronim rezultat din sarcina acesteia. În tabelul din figura
2.10 sunt date câteva funcþii uzuale.

SENS Explicaþia
NUME FUNCÞIE EFECT
CONVERSIE acronimului
ºir → numãr atoi(sir) Transformã ºirul de cifre în valoare numericã întreagã. ASCII to int
atol(sir) Transformã ºirul de cifre în valoare numericã long. ASCII to long
atof(sir) Transformã ºirul de cifre în valoare numericã realã ASCII to float
dublã precizie. Dacã ºirul conþine mai multe puncte
zecimale, conversia se opreºte la al doilea. Funcþia
întoarce 0 dacã nu poate converti ºirul în numãr.
numãr → ºir itoa(n,sir,b) Transformã numãrul n din baza b în ºir de caractere. int to ASCII
ltoa(n,sir,b) Transformã numãrul n din baza b în ºir de caractere. long to ASCII
Figura 2.10

Sarcinã de laborator: Sã se inspecteze funcþiile din fiºierul antet stdlib.h cu ajutorul programului de
asistare – help – al mediului de programare.

SIRURI
, DE CARACTERE
45 45
1. Scrieþi secvenþa de prelucrãri prin care se realizeazã sarcina funcþiei atoi pentru ºirul citit în
variabila S, considerând cã nu existã funcþia respectivã în biblioteca limbajului.
2. Scrieþi secvenþa de prelucrãri prin care se realizeazã sarcina funcþiei atof pentru ºirul citit în
variabila S, considerând cã nu existã funcþia respectivã în biblioteca limbajului.
3. Scrieþi secvenþa de prelucrãri prin care se realizeazã sarcina funcþiei itoa pentru ºirul citit în
variabila S, considerând cã nu existã funcþia respectivã în biblioteca limbajului.

2.7. Validarea sintacticã a datelor de intrare


Prelucrarea eºueazã dacã datele de intrare sunt introduse cu erori. Acest lucru se întâmplã dacã utilizatorul
unui program este o persoanã oarecare, fãrã cunoºtinþe de informaticã sau având cunoºtinþe precare. Chiar ºi un
utilizator experimentat poate greºi la introducerea valorilor, din grabã sau din neatenþie. Sarcina expresã a oricãrei
prelucrãri a datelor este sã asigure validarea datelor de intrare (testele de corectitudine). Validarea presupune douã
forme.
Formele de validare:
– validarea sintacticã stabileºte corectitudinea formei în care intrã o valoare;
– validarea logicã stabileºte corectitudinea conþinutului datei.
Validarea sintacticã se bazeazã pe forma de ºir de caractere sub care intrã iniþial valoarea. ªirul este verificat
din punct de vedere sintactic ºi apoi conþinutul ºirului este convertit în tipul de reprezentare pe care trebuie sã-l
aibã acea valoare în prelucrãrile ulterioare.
Altfel, valoarea greºitã ar intra direct în variabila cãreia îi este destinatã ºi ar apãrea o contradicþie de tip
de reprezentare, finalizatã cu întreruperea, cu eroare, a programului.
De asemenea, unele validãri logice se servesc de forma intermediarã de tip ºir de caractere pentru situaþiile
în care, deºi scrise corect, valorile nu ar intra în limitele necesare prelucrãrii. De exemplu, o variabilã de tip int
ar primi valoarea 70 000, ceea ce ar produce o eroare logicã, deºi 70 000 este corect scris ca numãr în sine. Astfel,
testat ca ºir de caractere, 70 000 va fi remarcat în afara domeniului de reprezentare pentru întregi, fãrã ca programul
sã ruleze în continuare cu valoarea greºitã.
Exerciþii rezolvate – validare sintacticã
Exerciþiile se vor pune în execuþie ca teme de laborator.
1) Se considerã situaþia în care se citeºte o fracþie zecimalã. Deoarece se poate greºi la tastarea
valorii, atunci se face o verificare sintacticã a datei introduse, înainte de a fi prelucratã ca numãr
real (float sau double). Greºelile sintactice pot consta în scrierea de caractere diferite de cifrã
sau în scrierea virgulei în loc de punctul zecimal.
Programul de mai jos preia informaþia tastatã în ºirul de caractere sir ºi îi aplicã funcþia atof
pentru a încerca transformarea în numãr real. Dacã funcþia reuºeºte transformarea, atunci va furniza
fracþia zecimalã corespunzãtoare, ca reprezentare internã în virgulã mobilã, iar dacã transformarea eºueazã, atunci
funcþia va întoarce valoarea zero.
//validarea sintactica a intrarii unei clrscr();
//fractii zecimale cout<<”Dati fractia zecimala ”;
#include<iostream.h> cin>>sir;
#include<conio.h> f=atof(sir);
#include<stdlib.h> if(f)cout<<”Fractia este corecta ”<<f;
void main() else cout<<”Fractia nu este corecta
{ char sir[20]; ”;
double f; getch();}

Cum funcþia atof nu sesizeazã situaþia în care se introduce chiar numãrul 0.0 ºi întoarce tot zero, ca pentru
eroare, trebuie ca transformarea sã se complice puþin, dupã cum este prezentatã în programul de mai jos, în care
se face testarea explicitã a caracterelor din ºirul sir.

46 CAPITOLUL 2
//validarea sintactica explicita if((sir[0]<‘0’||sir[0]>’9')&&sir[0]!=’-’)
//a unei fractii zecimale ok=0;
#include<iostream.h> else
#include<string.h> for(int i=1;sir[i]&&ok;i++)
#include<conio.h> if((sir[i]<‘0’||sir[i]>’9'||sir[i]==’,’)
#include<stdlib.h> && sir[i]!=’.’)
void main() ok=0;
{char sir[20],*p; if(ok)
double f; int ok=1; {f=atof(sir);
clrscr(); cout<<”Dati fractia zecimala ”; cout<<”Fractia este corecta ”<<f;
cin>>sir; }
p=strchr(sir,’.’); else cout<<”Fractia nu este corecta ”;
if(p) getch();
{p=strchr(p+1,’.’); }
if(p) *p=NULL; }//oprire la primul •

2) Se considerã situaþia în care se citeºte o notã ºcolarã. La citirea valorii, pot apãrea erori de tastare, în
sensul cã se poate introduce alt caracter decât cifrã sau se pot introduce valori care nu sunt note, adicã sunt în
afara limitelor 1 ºi 10. Programul de mai jos prezintã o modalitate de a verifica dacã valoarea introdusã de la
tastaturã este o notã sau nu. S-a folosit funcþia atoi.
//validarea unei note scolare cout<<”Dati nota scolara ”;
#include<iostream.h> cin>>a;
#include<string.h> //conversie sir in nr. natural
#include<conio.h> nota=atoi(a);
#include<stdlib.h> if(nota<1 || nota>10)
void main() cout<<”Nota este eronata ”;
{ char a[3]; else
unsigned nota; cout<<”Nota este corecta: ”<<nota;
clrscr(); getch();
//citire nota }

Sarcini de laborator. Rulaþi programul de mai sus pentru situaþia în care ºirul de intrare este ”1a” în loc de
”10”. Notaþi ce se afiºeazã ºi rulaþi apoi pas cu pas pentru a vedea modificarea valorilor în variabilele programului.
3) Se citeºte o succesiune de maximum 8 caractere, din mulþimea {‘0’, ’1’, ’2’, ’3’, ’4’, ’5’, ’6’, ’7’, ’8’, ’9’,
’A’, ’B’, ’C’, ’D’, ’E’, ’F’}, care reprezintã un numãr scris în baza 16. Primul caracter nu trebuie sã fie ‘0’. Sã se afiºeze
valoarea în baza 10 a numãrului hexazecimal.
Rezolvare. Se considerã scrierea polinomialã a unui numãr într-o bazã oarecare, b:
an . bn + an-1 . bn-1 + … + a1 . b1 + a0 . b0
unde cu ai (cu i de la n la 0) s-au notat cifrele numãrului în baza b. Evaluarea polinomului va consta în calculul
progresiv, înlocuind coeficienþii cu valoarea cifrei respective în baza 16, iar pe b cu 16, pe baza grupãrii Horner:
(…((an +0)×b + an-1 )× b + … )× b+ a1 )× b1 + a0 × b0.
//transformare din baza 16 in baza 10 for(i=0;i<n;i++)
#include<iostream.h> if(!((h[i]>=’0'&& h[i]<=’9')||
#include<conio.h> (h[i]>=’A’&& h[i]<=’F’))) x=0;
#include<string.h> if(x)
void main() for(i=0;i<n;i++)
{ {if(h[i]>=’0'&&h[i]<=’9')
long nz=0;char h[8];int rest,i,x,n; rest=h[i]-’0';
clrscr(); else
cout<<”Dati nr. hexa ”; rest=h[i]-’A’+10;
cin>>h; nz=nz*16+rest;
strupr(h);//transf. in litere mari }
n=strlen(h); cout<<”Nr.in baza zece : ”<<nz;
x=1; getch();}
SIRURI
, DE CARACTERE
47 47
Sarcini de laborator. Adãugaþi în program testul pentru zerourile nesemnificative (ignorarea primelor ca-
ractere de tip cifrã zero pânã la întâlnirea primului caracter hexa de tip cifrã semnificativã).
4) Validarea sintacticã a unei date calendaristice introdusã în formatul numeric: zz/ll/aaaa, unde zz este
numãrul zilei, ll este numãrul lunii ºi aaaa este numãrul anului.
Rezolvare. Programul verificã dacã s-a folosit separatorul ’/’ ºi dacã în zonele datei sunt cifre. De asemenea,
se verificã (ceea ce nu era obligatoriu pentru validarea sintacticã), dacã cifrele care alcãtuiesc ziua ºi luna sunt
între limitele de scriere ale unei zile ºi, respectiv, ale unei luni din calendar. Urmeazã ca în alt program sã fie fãcutã
validarea logicã a datei (corectitudinea valoricã), dupã ce grupele numerice ale datei au fost transformate în nu-
mere. A fost organizatã constanta mes pentru a furniza textul erorii pe care o va afiºa programul. Vectorul este,
cu patru elemente întregi, va înregistra valoarea 1 în componenta de indice corespunzãtor indicelui textului erorii
din vectorul mes: de exemplu, este[0]←1, dacã s-a întâlnit un separator greºit (adicã eroarea mes[0]).
//program validare_sintactica numeric: zi/luna/an ”;
//data calendaristica; cin>>a;
#include<iostream.h> if(a[2]!=’/’||a[5]!=’/’)este[0]=1;
#include<string.h> if(a[0]<‘0’||a[0]>’3'||a[1]<‘0’||a[1]>’9')
#include<conio.h> este[1]=1;
#include<stdlib.h> if(a[3]<‘0’||a[3]>’1'||a[4]<‘0’||a[4]>’2')
void main() este[2]=1;
{const char for(i=0;i<3;i++)
mes[4][17]={”Separator gresit”,”Zi if(a[i+6]<‘0’||a[i+6]>’9') este[3]=1;
gresita”,”Luna gresita”,”an gresit”}; for(i=0;i<4;i++)
char a[11]; if(este[i]) cout<<mes[i]<<endl;
int este[4]={0},i; getch();
cout<<”Introduceti data in format }

Sarcini de laborator:
1. Realizaþi un program în care sã se valideze logic o datã calendaristicã scrisã în format numeric zz/ll/aaaa.
2. Transformaþi programul de mai sus, astfel încât sã folosiþi funcþii din biblioteca string.

1. Care dintre cele douã secvenþe de mai jos afiºeazã prima literã micã din ºirul a?
i=0; while(a[i]&& (a[i]<‘a’||a[i]>’z’))
i++; cout<<a[i];
i=0;do i++;
while(a[i]&&!(a[i]>=’a’&&a[i]<=’z’));
cout<<a[i];
2. Care dintre operaþiile de scriere din secvenþa de mai jos afiºeazã textul aa?
char a[4][2]={”xa”,”ax”,”ya”,”ay”}; cout<<a[3][0]<<a[1][0];
cout<<a[[1][0]<<a[2][1]; cout<<a[1][1]<<a[2][0];
3. Stabiliþi valoarea de adevãr a afirmaþiei: pentru trei variabile de tip ºir de caractere, declarate:
char s1[10],s2[10],s3[10]; instrucþiunea if(strcmp(s1,s2)&&strcmp(s2,s3))
cout<<1; va afiºa 1 dacã toate cele trei ºiruri sunt egale.
4. Pentru declarãrile de variabile: char s[4]=”123",t[4]; int x=123,y; care dintre expresiile
urmãtoare au valoarea zero?
a) atoi(s)!=x; b) itoa(x,t,10)==s; c)!strcmp(itoa(x,t,10),s);
d) x==(atoi(itoa(x,t,10));
5. Care dintre urmãtoarele prelucrãri sunt scrise greºit, ºtiind cã se dau declarãrile: char *p, s[10]?
a) p=strchr(‘m’,s); b) p=strstr(s,”ma”)-s; c) cout<<strlen(”sir”);
d) cout<<strcat(”con”,”cat”);
6. Ce se va afiºa în urma executãrii secvenþei de mai jos ?
char s[10]=”Amalia”; for(int i=1;i<4;i++) strcpy(s+1,s+2); cout<<s;

48 CAPITOLUL 2
7. Ce se va afiºa în urma executãrii secvenþei de mai jos?
char s[10]=”Amalia”,*p; s[0]=s[0]+32;
p=strchr(s,’i’);cout<<s[0]<<p[0]<<s[strlen(s)-1];

PROBLEME PROPUSE

Pentru problemele de mai jos se vor realiza programele corespunzãtoare în cazurile generale.
1) Sã se afiºeze câte caractere albe sunt într-un ºir de caractere citit.
2) Se dã un ºir de caractere; sã se întoarcã ºirul invers, în aceeaºi zonã de memorie, ºi sã se afiºeze
rezultatul.
3) Se citeºte dintr-un fiºier un text terminat cu caracterul punct. Sã se stabileascã numãrul de litere, numãrul
de separatori ºi numãrul de cuvinte din text. Cuvintele sunt separate prin spaþii albe, punct ºi vigulã
sau douã puncte.
4) Se dã un ºir de caractere; sã se afiºeze un mesaj corespunzãtor dacã ºirul este palindrom sau nu.
5) Se dã un ºir de caractere S; sã se afiºeze de câte ori se regãseºte în el subºirul s (citit) încadrat de câte
un spaþiu. Dacã ºirul s apare chiar la începutul ºirului S, el trebuie sã fie urmat de un spaþiu.
6) Se citeºte un ºir de caractere care reprezintã scrierea unei fracþii zecimale oarecare. Dacã fracþia zecimalã
este corectã, sã se transforme în fracþie ordinarã ºi sã se afiºeze numãrãtorul ºi numitorul obþinute.
7) Se citesc maximum 20 de cuvinte reprezentând nume de culori. Sã se afiºeze câte seturi de culori ale
spectrului au intrat, prin set înþelegând o succesiune secvenþialã de nume de culori cu proprietatea
cerutã.
8) Dându-se data curentã ºi numele din sãptãmânã al zilei în care a fost 1 ianuarie al anului curent, sã se
afiºeze numele zilei desemnat de data curentã.
9) Se citeºte un numãr în baza 10. Sã se afiºeze valoarea respectivã scrisã în baza 16.
10) Se citesc n ºiruri de caractere care ar reprezenta mediile generale ale unor elevi. Sã se calculeze me-
dia generalã a grupului, dacã datele de intrare sunt corecte.
11) În fiºierul rebus.txt, pe prima linie se aflã o valoare naturalã care se va citi în variabila n. Apoi se
citesc n linii ce reprezintã conþinutul orizontalelor dintr-un careu de rebus. Punctele negre sunt re-
prezentate prin caracterul *. Sã se afiºeze n linii care reprezintã conþinutul verticalelor careului.
12) Pentru aceleaºi condiþii ca în problema 10, sã se determine numãrul de cuvinte din careu, ºtiind cã un
cuvânt are minimum douã litere.
13) Se citeºte un text de la tastaturã. Din acest text sã se extragã constantele numerice ºi sã se adune.
Programul va afiºa suma obþinutã. Exemplu: dacã se citeºte ºirul ab12x!345 se va afiºa suma 357
obþinutã din 12 + 345.
14) Scrieþi un program prin care se realizeazã prelucrarea pe care o face funcþia strstr dar determinã
un întreg ce reprezintã poziþia în ºir unde începe subºirul cãutat, sau –1 în cazul în care subºirul nu
este gãsit.
15) Temã pentru portofoliu. Sã se elaboreze un program care citeºte din fiºierul text.in câte un cuvânt
de pe fiecare linie ºi afiºeazã acel cuvânt despãrþit în silabe. Se utilizeazã urmãtoarele reguli de despãr-
þire în silabe, fãrã a se trata excepþiile:
– o consoanã aflatã între douã vocale trece în silaba a doua;
– pentru douã sau mai multe consoane aflate între douã vocale, prima rãmâne în silaba întâi, iar celelalte
trec în silaba a doua.

SIRURI
, DE CARACTERE
49 49

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