Programul de numărare a cuvintelor
Pentru a exersa lucrul cu șiruri de caractere, vom scrie un mic program care numără cuvintele dintr-un text introdus de utilizator.
#include <iostream>
#include <vector>
#include <string>
int main()
{
std::string text; // Textul sursă
std::cout << "Enter some text: ";
std::getline(std::cin, text);
const std::string separators{ " ,;:.\"!?'*\n" }; // separatori de cuvinte
std::vector<std::string> words; // vector pentru stocarea cuvintelor
size_t start { text.find_first_not_of(separators) }; // indexul primului caracter al primului cuvânt
while (start != std::string::npos) // continuăm cât timp există caractere care nu sunt separatori
{
size_t end = text.find_first_of(separators, start + 1); // găsim sfârșitul cuvântului
if (end == std::string::npos) // dacă nu am găsit niciun separator
end = text.length(); // setăm sfârșitul la finalul textului
words.push_back(text.substr(start, end - start)); // adăugăm cuvântul în vector
start = text.find_first_not_of(separators, end + 1); // căutăm începutul următorului cuvânt
}
// afișăm numărul de cuvinte
std::cout << "\nText contains " << words.size() << " words:" << std::endl;
// afișăm toate cuvintele
for (const auto& word : words)
{
std::cout << word << std::endl;
}
}
Explicații pas cu pas:
- Definim variabila text care va conține textul introdus de la tastatură:
std::string text; // Textul sursă
std::cout << "Enter some text: ";
std::getline(std::cin, text);
- Definim un șir de caractere separatorii, ce includ semnele de punctuație, spații și caracterul de linie nouă (\n), care nu fac parte din cuvinte:
const std::string separators{ " ,;:.\"!?'*\n" }; // separatori de cuvinte
Notă: caracterul \n este inclus mai mult demonstrativ, deoarece folosind std::getline() citirea textului se termină la apăsarea tastei Enter, deci șirul introdus nu va conține \n. Dar dacă s-ar citi text dintr-un fișier sau cu altă metodă, \n ar putea apărea și ar trebui luat în calcul.
- Deoarece numărul cuvintelor nu este cunoscut, folosim un vector pentru a le stoca:
std::vector<std::string> words; // vector pentru cuvinte
- Găsim indexul primului caracter care nu este separator, adică începutul primului cuvânt:
size_t start { text.find_first_not_of(separators) };
- Într-o buclă while, continuăm cât timp start este un index valid:
while (start != std::string::npos)
Dacă textul ar conține doar separatori, find_first_not_of() va returna std::string::npos, iar bucla se va opri.
- Găsim sfârșitul cuvântului curent căutând primul caracter separator după poziția start:
size_t end = text.find_first_of(separators, start + 1);
Dacă nu se găsește niciun separator (de exemplu, cuvântul este ultimul din text), atunci:
if (end == std::string::npos)
end = text.length();
- Extragem cuvântul cu substr() și îl adăugăm în vector:
words.push_back(text.substr(start, end - start));
- Actualizăm start la poziția primului caracter care nu este separator după end:
start = text.find_first_not_of(separators, end + 1);
- După terminarea buclei, afișăm numărul de cuvinte și fiecare cuvânt:
std::cout << "\nText contains " << words.size() << " words:" << std::endl;
for (const auto& word : words)
{
std::cout << word << std::endl;
}
Exemplu de rulare a programului:
Enter some text: When in Rome, do as the Romans do.
Text contains 8 words:
When
in
Rome
do
as
the
Romans
do