Operații cu simboluri
Biblioteca standard C++ oferă o serie de funcții încorporate pentru lucrul cu caractere. Acestea sunt utilizate în principal pentru verificarea caracterelor:
- isupper(c): verifică dacă c este o literă mare (în mod implicit, de la 'A' la 'Z')
- islower(c): verifică dacă c este o literă mică (în mod implicit, de la 'a' la 'z')
- isalpha(c): verifică dacă c este un caracter alfabetic
- isdigit(c): verifică dacă c este o cifră, de la '0' la '9'
- isxdigit(c): verifică dacă c este o cifră hexazecimală (0–9, a–f, A–F)
- isalnum(c): verifică dacă c este alfanumeric, echivalent cu isalpha(c) || isdigit(c)
- isspace(c): verifică dacă c este un spațiu (' '), newline ('\n'), carriage return ('\r'), form feed ('\f'), tab orizontal ('\t') sau tab vertical ('\v')
- isblank(c): verifică dacă c este spațiu (' ') sau tab ('\t')
- ispunct(c): verifică dacă c este un semn de punctuație (ex: _ { } [ ] # ( ) < > % : ; ? * + - / ^ & | ~ ! =)
- isprint(c): verifică dacă c este un caracter printabil (litere, cifre, semne de punctuație, spațiu)
- iscntrl(c): verifică dacă c este un caracter de control (neprintabil)
- isgraph(c): verifică dacă c are o reprezentare grafică (caracter vizibil)
- tolower(c): convertește caracterul c în literă mică
- toupper(c): convertește caracterul c în literă mare
Exemplu, verificăm registrul unui caracter:
#include <iostream>
int main()
{
unsigned char letter {'a'};
if (std::isupper(letter))
std::cout << "Uppercase letter" << std::endl;
else if (std::islower(letter))
std::cout << "Lowercase letter" << std::endl;
else // dacă nu este literă
std::cout << "Undefined" << std::endl;
}
Aceste funcții sunt foarte utile la procesarea șirurilor. Să analizăm o sarcină simplă – extragerea numărului de telefon dintr-un text, de exemplu: "Phone number: +1(234)456-78-90":
#include <iostream>
#include <string>
int main()
{
std::string text {"Phone number: +1(234)456-78-90"};
std::string phone; // șir pentru numărul de telefon
for(unsigned i{}; i < text.length(); i++)
{
// verificăm dacă caracterul este cifră
if(std::isdigit(text[i]))
{
// adăugăm caracterul în șirul phone
phone += text[i];
}
}
std::cout << phone << std::endl; // 12344567890
}
Pe de o parte, am putea folosi simpla operație de comparație ==, care poate compara și șiruri. Dar dacă încercăm să comparăm două șiruri în care cel puțin un caracter diferă prin registru, ele vor fi considerate diferite:
#include <iostream>
#include <string>
int main()
{
std::string word1 {"HELLO"};
word1 = "hello";
std::string word2 {"hello"};
if(word1 == word2)
{
std::cout << "strings are equal" << std::endl;
}
else
{
std::cout << "strings are not equal" << std::endl;
}
}
Rezultatul acestui program:
strings are not equal
Pentru a organiza o comparație fără a ține cont de registru, am putea converti caracterele în litere mari sau mici și apoi să le comparăm:
#include <iostream>
#include <string>
int main()
{
std::string word1 {"HELLO"};
std::string word2 {"hello"};
bool is_equal{true}; // presupunem că sunt egale
if(word1.length() != word2.length())
{
is_equal = false;
}
else
{
// comparăm toate caracterele
for(unsigned i{}; i < word1.length(); i++)
{
// convertim caracterele în litere mici și le comparăm
if(std::tolower(word1[i]) != std::tolower(word2[i]))
{
// dacă caracterele nu sunt egale, resetăm flagul de egalitate
is_equal = false;
break; // ieșim din buclă
}
}
}
if(is_equal)
{
std::cout << word1 << " and " << word2 << " are equal" << std::endl;
}
else
{
std::cout << word1 << " and " << word2 << " are not equal" << std::endl;
}
}
În acest caz, mai întâi comparăm lungimea șirurilor, pentru că dacă lungimile sunt diferite, șirurile sunt clar diferite.
Apoi, în buclă, parcurgem toate caracterele ambelor șiruri, le convertim în litere mici și le comparăm. Dacă măcar o pereche de caractere corespunzătoare nu este egală, atunci resetăm flagul de egalitate is_equal la false și ieșim din buclă, deoarece în acest caz șirurile nu mai pot fi egale, iar continuarea comparării nu are rost.
Rezultatul acestui program:
HELLO and hello are equal