Sunteți pe pagina 1din 7

Conținuturi:


Săptămâna 14:
Caractere în limbajul C
 Citirea și scrierea șirurilor de
caractere
Șiruri de caractere  Transformarea unei litere din
mică/mare
 Cum separăm șirul în cuvinte?
Caractere în limbajul C

În limbajul C avem variabile și expresii de tip caracter. O variabilă de tip caracter poate stoca un
singur caracter și se declară astfel:
char c;
Unei astfel de variabile putem să-i atribuim un caracter:
char c = 'a';
Constantele caracter, cum ar fi 'a', se specifică între apostroafe, pentru a se deosebi de
numele unei variabile. În urma instrucțiunii de mai sus variabila c va stoca valoarea 'a'. În realitate
valoarea stocată va fi un număr, și anume codul ASCII al caracterului 'a', adică 97. Deoarece
calculatorul cunoaște tabela codurilor de caractere, el face automat conversia de la 'a' la 97, fără a fi
nevoie ca noi să reținem acest număr.
Identitatea între caractere și coduri ASCII
În limbajul C nu se face distincție între un caracter și codul lui ASCII. Aceasta înseamnă ca
următoarele două instrucțiuni sînt echivalente:
c = 'A';
c = 65;
În primul caz atribuim caracterul 'A' variabilei c. În realitate variabila c va stoca codul ASCII al
acelui caracter, adică 65. În al doilea caz îi atribuim numărul 65. Dar variabila c fiind de tip caracter
calculatorul va ști că 65 este de fapt codul caracterului 'A'.
Ce va face următoarea secvență?
char c;
c = 'A';
c = c + 1;
if ( c == 'B' )
cout<< "la caractere se poate aduna un numar";
Prima instrucțiune va depune caracterul 'A' în variabila c. În realitate c va stoca codul ASCII al
lui 'A', adică 65. Următoarea instrucțiune va aduna 1 la c, noua lui valoare fiind 66. Prin
echivalență, aceasta este tot una cu caracterul 'B', deci programul va afișa textul din cout.
Citirea și afișarea unui caracter:
Citirea în C++:
char c;
cin>>c; //citire
cout<<c; //afișare

Citirea în C:
scanf(”%c”,&c);
printf(”%c”,c);
fscanf(nume_fisier,”%c”,&c); //citire din fișier
fprintf(nume_fisier,”%c”,c); //afisare în fișier
Deși fscanf/fprintf poate citi/afișa caractere folosind descriptorul %c această metodă nu este
recomandată. În locul lui fscanf vom folosi perechea de funcții fgetc/fputc, astfel:
c = fgetc(fin); //citește din fișierul fin un char și-l memorează în
variabila c
fputc( c, fout ); // scrie caracterul c in fișierul fout

Putem să testăm dacă un caracter este litera mare, litera mica sau cifră.

Cum putem testa dacă a este un Expresia a >= ’0’ && a <= ‘9’ va avea valoare true(1)
caracter de tip cifră dacă variabila a este cifră
Cum putem testa dacă a este o literă Expresia a >= ’A’ && a <= ‘Z’ va avea valoare true(1)
mare dacă variabila a este literă mare
Cum putem testa dacă a este o literă Expresia a >= ’a’ && a <= ‘z’ va avea valoare true(1)
mică dacă variabila a este literă mică

Se numesc caractere albe acele caractere ca fiind acelea care afișate pe ecran nu au un rezultat
vizibil (exemplu: spațiu, enter, tab, etc). Un astfel de caracter este '\n'. La fel este caracterul TAB,
care se codează cu '\t'. Precum vedeți ele se codifică prin două caractere, din care primul
este backslash. Secvența din două caractere, primul fiind \ se mai numește și secvență escape.
Aceasta vine de la verbul englezesc "a scăpa", deoarece caracterul \ schimbă sensul următorului
caracter, sau, cu alte cuvinte, scapă de restricțiile codificării normale a limbajului C.

Ce alte caractere speciale mai avem? Un alt caracter este chiar apostroful. Dacă am vrea să folosim
caracterul apostrof și am scrie ''' (trei apostroafe) compilatorul de C ar lega primele două apostroafe,
considerînd caracterul vid, cel de-al treilea apostrof fiind începutul unui nou caracter, cea ce va
genera o eroare de compilare. De aceea caracterul apostrof se codifică cu '\'' (\' între două
apostroafe). Similar este cu caracterul ghilimele sau ’\’.
Iată un scurt exemplu de secvență de program care afișează toate literele mari din alfabetul englez:
char c;
for ( c = 'A'; c <= 'Z'; c++ )
cout<< c<<” ”;

Citirea și scrierea șirurilor de caractere


Limbajul C nu dispune de un tip de date nativ pentru reprezentarea șirurilor de caractere de lungime
variabilă. În acest scop se utilizeaza structuri de date de tip tablou de caractere. Un șir de caractere
este, de fapt, o succesiune de caractere.
Întrucât șirurile de caractere prelucrate în programe au în general lungime variabilă, s-a stabilit o
convenție prin care ultimul caracter utilizat al unui șir este urmat de un caracter cu valoarea zero ('\
0'), numit terminator de șir.
O constantă de tip șir de caractere se declară între doua caractere “. În memoria internă, o constantă
de acest tip este reținută sub forma unui vector de caractere. Fiecare componentă a șirului (începând
cu cea de indice 0) reține codul ASCII al caracterului pe care îl memorează. Caracterul nul este
memorat automat. Trebuie rezervate lungimea șirului+1 caractere char (+1 pentru caracterul nul).

Declarația unui șir:


char c[25];

Declarație și inițializare:
char s[6] = {’a’, ’b’, ’c’, ’d’, ’e’};
char sir[5] = {’a’, ’b’, ’c’, ’d’, ’\0’};
char s[5] = ”abcd”;

Un şir de caractere poate fi iniţializat la declarare astfel:


char cuvant[ ]=”programator”;
În urma iniţializării, la sfârşitul cuvântului va fi adăugat caracterul 0 (codul ASCII al caracterului
nul ).
p r o g r a m a t o r 0
0 1 2 3 4 5 6 7 8 9 10 11

Compilatorul va calcula numărul de octeţi necesari pentru memorarea cuvântului programator. În


acest caz tabloul conţine 12 octeţi, 11 pentru memorarea cuvântului şi 1 pentru memorarea codului
caracterului nul.

char cuvant[ 15]=”programator”;


p r o g r a m a t o r 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
În acest caz am memorat un vector de 15 octeţi, mai mulţi decât sunt necesari. Ultimii trei octeţi
rămân neutilizaţi.

Citirea și afișarea șirurilor de caractere

Fie următoarea declarație:


char s[256]; - s-a declarat un șir de caractere cu numele s, ce poate memora maximum 255 de
caractere.

Citirea șirului s se poate face utilizând operatorul uzual de citire >> : cin>>s;
În acest caz se vor citi în șirul s toate caracterele până la primul caracter alb (spațiu, tab, enter). De
exemplu, dacă fluxul de intrare conține caracterele “Buna ziua”, după citire, șirul s va fi Buna.

Funcţia cin procedează astfel la citirea unui şir de caractere:


 Se sar toate caracterele albe
 Se citește şirul care începe cu primul caracter care nu este alb
 Citirea se încheie la întâlnirea primului caracter alb

Pentru a elimina acest dezavantaj se pot folosi funcțiile get( ) sau getline( ) (diferența între ele este
că getline() extrage din fluxul de intrare caracterul delimitator, în timp ce get() nu îl extrage). Dacă
totuși doriți să folosiți numai funcția get, atunci după citirea fiecărui șir trebuie să scrieți funcția
cin.get() fără parametri.

Sintaxa:
cin.get(nume_sir,lungimea_sirului);
cin.getline(nume_sir,lungimea_sirului,delimitator); - unde delimitatorul
este optional (implicit este caracterul ' \ n’.

Transformarea litere mici/mari


O variabila de tipul char poate lua valori întregi din intervalul [-128, 127]. Constantele de tip char
pot fi numere întregi sau caracterele care au codurile ASCII în intervalul specificat anterior.
Din exemplele prezentate tragem concluzia că literele mari și literele mici au alocate numere
diferite (codurile lor ASCII sunt diferite). Codul literei 'A' este mai mic cu 32 decît codul literei 'a'.
Răspuns: observăm că aceeași relație se păstrează și între 'B' și 'b', 'C' și 'c', etc. Ceea ce ne duce la o
primă concluzie:
c = c-32;

Problema este că trebuie să ținem minte acest număr, 32. În plus, daca vrem să facem conversia
invers, de la litere mari la litere mici, va trebui sa adunăm 32 în loc să scădem. De aceea vom folosi
o variantă mai elegantă:
c = 'A' + c - 'a';

Separarea cuvintelor dintr-un șir de caractere


În general se specifică în probleme că șirul conține cuvinte separate de spații. Uneori pot fi și alți
separatori precum ’.’ sau ’,’. Ca să identificăm un cuvânt putem folosi:
 o variabilă logică care să țină minte dacă suntem în interiorul unui cuvânt sau nu (aceasta
se setează pe 1 cand întâlnim un caracter diferit de separator și devine zero când întâlnim un
spațiu)
reținem poziția de început a cuvântului și cea de sfârșit (vezi problema propusă cu
cuvinte).
În general un cuvânt este o identitate care se delimitată de spații. Excepție de la această regulă –
primul cuvânt din șir și ultimul cuvânt. Putem adăuga dupa ultimul cuvânt un spațiu.
Memorarea mai multor șiruri de caractere
Pentru a reține mai multe cuvinte (sau chiar șiruri), fiecare separat, trebuie să folosim o matrice de
caractere, fiecare linie a matricii va reține câte un cuvânt (șir). De reținut că prima linie a matricii se
poate accesa prin a[0], a doua: a[1].
char a[20][20]; // putem retine 20 de cuvinte, fiecare a cate 20 de
litere
cout<<a[2];// se va afisa linia a 3-a a matricii

Aplicaţii practice

1. Se citesc n caractere din fișierul date.in și va afișa dacă toate sunt litere.
Rezolvare:
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
int n, i;
char c;
ifstream fin("date.in");
fin>>n;
i = 0;
fin>>c;
while ( i < n && (('a' <= c && c <= 'z') || ('A' <= c && c <=
'Z')) ) {
fin>>c;
i++;
}
fin.close();

ofstream fout("date.out");
if ( i < n ) // am gasit un caracter care nu e litera
fout<< "Nu sunt numai litere\n";
else // inseamna ca i == n, deci toate caracterele au
fost litere
fout<< "Sunt numai litere\n";
fout.close();
return 0;
}

2. Scrieți un program care citește de la tastatură un șir de maximul 100 caractere care conține
numai litere mici ale alfabetului englez și spații. Să se afișeze litera/literele care apar de cele
mai multe ori.
Rezolvare:
#include <iostream>
#include <fstream>
#include<cstring>
using namespace std;

int main()
{
int n, i;
char s[100];
ifstream fin("date.in");
fin.getline(s, 100);
fin.close();
int aparitii[30], Max_ap;
Max_ap=0;
for(i=0; i<='z'-'a'; i++)
aparitii[i]=0;
for(i=0; i<strlen(s); i++)
if(s[i]!=’ ‘)
aparitii[s[i]-'a']++; //numărăm litera intr-un vector de frecventa
for(i=0; i<='z'-'a'; i++)
if(aparitii[i]>Max_ap)
Max_ap = aparitii[i]; //calculam maximul de aparitii al unei
litere
ofstream fout("date.out");
for(i=0; i<='z'-'a'; i++)
if(aparitii[i]== Max_ap)
fout<<(char)(i+'a')<<" ";
fout.close();
return 0;
}

3. Se citește din fișier o secvență formată din maxim 100 de litere mici, până la întâlnirea
caracterului punct. Dacă în secvența dată se găsesc litere alăturate egale, aceste litere vor fi
eliminate. Dacă în urma eliminării se obțin din nou secvențe alăturate egale, se elimină și
acestea, eliminările efectuîndu-se până când în secvență nu există litere alăturate egale.
(propusă de Ema Cerchez)

#include <iostream>
#include <fstream>
#include<cstring>
using namespace std;

int main()
{
int n, i,j, k, schimb;
char s[100],c;
ifstream fin("date.in");
n=0; //numarul de litere din sir
do{
fin>>c;
if(c!='.')
s[n++]=c;
} while(c!='.');
fin.close();

do
{
schimb = 0;
i=0;
while(i<n-1)
if(s[i]==s[i+1]){ //incepe o secventa de caractere egale
//determin sfarsitul acestei secvente
for(j=i+1; j<n &&s[j]==s[i] ; j++);
// o elimin
for(k=j;k<=n;k++)
s[i+k-j] = s[k];
n=n-(j-i);
schimb =1;}
else
i++;
} while(schimb == 1);
ofstream fout("date.out");
fout<<s;
fout.close();
return 0;
}

4. Se citește din fișier un șir de maximul 100 de caractere. Se cere să se șteargă din fișier toate
cuvintele care au lungimea egală cu 3. Cuvintele sunt separate printr-un singur spațiu și
primul cuvânt începe de la poziția 0.

#include <fstream>
#include <iostream>
using namespace std;

int main()
{
ifstream fin("date.in");
char s[100];
int n,i;
fin.getline(s,100);
//calculam lungimea sirului
n=0;
i=0;
while(s[i]!='\0')
n++, i++;
s[n]=' ';
s[n+1]=NULL; //adaugam un spatiu dupa ultimul cuvant
n++;
int inc, sf, l,k,j;
inc =0; // primul cuvant incepe de pe pozitia 0
i=0;

while(i<n)
if(s[i]==' ')
{
l=i-inc;
if(l==3)
{
j=inc;
k=inc+4;//stergem cuvantul cu tot cu spatiul de dupa el
while(s[k]!='\0')
{
s[j]=s[k];
j++;
k++;
}
n=n-4;
s[n]='\0';
i=inc-1;
}
else
{
i++;
inc = i;//fixez inceputul urmatorului cuvant
}
}
else
i++;
ofstream fout("date.out");
fout<<s;
fout.close();
return 0;
}

Aplicații propuse spre rezolvare


1. Sumacifre (viarena)
Se citesc n caractere, să se afişeze suma cifrelor din şir.

Date de intrare: Fişierul de intrare sumacifre.in conţine pe prima linie numărul de caractere n. Pe a
doua linie conţine n caractere.
Date de ieșire: În fişierul de ieşire sumacifre.out se va scrie suma tuturor cifrelor aflate în datele de
intrare.
Restricții: 1 ≤ n ≤ 2 000 000

Exemplu:
sumacifre.in sumacifre.out
20 25
a7; 4$dDt047Tt@p p&3

2. Caractere (pbinfo)
Se dau 2 șiruri de caractere. Să se afișeze toate caracterele primului șir ce se
găsesc și în al doilea
Date de intrare: Programul citește de la tastatură 2 șiruri de caractere, dispuse
pe 2 linii.
Date de ieșire: Programul va afișa pe ecran toate caracterele primului șir ce se
găsesc și în al doilea
Restricții:
 fiecare șir citit va conține cel mult 250 de caractere;
 caracterele vor fi afișate în ordinea în care se găsesc în primul șir
Exemplu:
caractere.in caractere.out
asD’ ”;*}! a’;
da’h

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