Resumo
O texto é o dado mais frequente de um programa: nomes, mensagens, linhas de um arquivo, comandos de um usuário. Esta aula o trata como o que ele é para o C++, uma sequência de caracteres com operações próprias. Apresenta std::string, que se cria, se concatena, se compara e se percorre como um vetor de char com ofício de texto; suas operações de busca e de extração (find, substr, starts_with, contains) e o valor std::string::npos, com o qual find diz que não encontrou nada; std::string_view, a visão que observa um texto sem copiá-lo, e a condição da qual ela depende: que o texto observado continue existindo. Fecham a aula as strings de C, para ler código alheio, e a ordem em que o C++ compara e ordena as palavras.
Objetivos de aprendizagem
- Usar as operações de
std::string(size,+,find,substr,starts_with,contains) para resolver problemas de texto. - Interpretar o resultado de
finde compará-lo comstd::string::npos, e prever o que acontece se ele for tratado como um número qualquer. - Receber texto em uma função como
std::string_viewe explicar com um exemplo por que uma visão não deve sobreviver à string que observa. - Ler código com strings de C e explicar suas diferenças em relação a
std::string: o terminador nulo, o tamanho fixo e a soma de dois literais, que não compila.
A string std::string
Criar, concatenar, percorrer
A aula Caracteres, booleanos, conversões e constantes apresentou o caractere, char, como um número pequeno que uma tabela converte em letra. Um texto é uma sucessão de caracteres; se isso é assim, ele pode ser guardado em um std::vector<char>, e o que a aula Vetores ensinou sobre as sequências valeria para ele. Ora, ao texto pedem-se operações que a uma sequência qualquer não se pedem: colar-lhe outro texto, buscar nele uma palavra, extrair um pedaço, escrevê-lo de uma vez. Disso se segue um tipo próprio, a string (cadeia de caracteres), std::string, do cabeçalho <string>: um vetor de char com ofício de texto.
#include <format>#include <print>#include <string>int main(){ const std::string first{"Ada"}; std::string greeting{"Oi, " + first}; greeting += '.'; std::println("{} ({} caracteres)", greeting, greeting.size()); std::println("Primeiro «{}», último «{}»", greeting[0], greeting.back()); int spaces{0}; for (const char c : greeting) { if (c == ' ') { ++spaces; } } std::println("Espaços: {}", spaces); const std::string code{std::format("{}-{:03}", "MAT", 7)}; std::println("{} {}", code, code == "MAT-007");}Oi, Ada. (8 caracteres)Primeiro «O», último «.»Espaços: 1MAT-007 trueA linha 7 cria uma string a partir de um literal. A 8 a concatena: o operador + entre uma string e um literal produz uma string nova com os caracteres de ambos, um em seguida do outro. A 9 acrescenta um caractere no final com +=, que também admite uma string ou um literal. O resto é o que já se sabia dos vetores: size() conta os caracteres (8, porque a vírgula, o espaço e o ponto também o são), greeting[0] é o primeiro e back() o último, e o laço das linhas 13 a 17 percorre a string caractere a caractere com a forma de intervalo da aula Laços. Como o vetor, uma string admite ainda push_back, pop_back e empty, e a biblioteca do GCC 15, quando não se otimiza, verifica seus índices com operator[] (com otimização, essa verificação desaparece).
As duas últimas linhas cumprem o que anunciou a aula Projetar com funções. std::format, de <format>, recebe os mesmos marcadores que std::println, com as mesmas especificações de formato ({:03} preenche com zeros até três algarismos), mas em vez de escrever o resultado o devolve como string: é a maneira de construir um texto que depois se guarda, se compara ou se passa a uma função. E == compara duas strings pelo seu conteúdo: são iguais se têm o mesmo tamanho e os mesmos caracteres na mesma ordem. Portanto, code == "MAT-007" é true, embora o texto da esquerda tenha sido construído por partes e o da direita seja um literal.
Comparar
Além de == e !=, as strings admitem <, <=, > e >=, que as comparam em ordem lexicográfica, a do dicionário: percorrem-se as duas lado a lado, e na primeira posição em que diferem decide o caractere menor; se uma se esgota antes sem diferença alguma, a mais curta é a menor. Assim, a string “bala” é menor que “bola”, porque 'a' < 'o' na segunda posição, e “sol” é menor que “solo”, porque a primeira é um prefixo da segunda. Os operadores comparam strings: entre dois literais escritos entre aspas comparam outra coisa, porque um literal não é um std::string, mas um arranjo, como se verá na seção sobre as strings de C. Qual caractere é “menor” é decidido pelo seu código, não pelo alfabeto; a última seção da aula mostra o que disso se segue.
Carregando o conteúdo…