Documente Academic
Documente Profesional
Documente Cultură
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<<” ”;
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”;
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.
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’.
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';
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>
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;
}
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