std::string: texto que se gerencia sozinho
Na página anterior você viu como ponteiros inteligentes permitem que um objeto seja dono de um recurso e o libere automaticamente. std::string é essa mesma ideia aplicada ao texto: ela possui um buffer de caracteres, faz ele crescer quando você anexa algo e o libera quando a string sai de escopo. Você nunca chama new, nunca conta bytes e nunca se preocupa com um terminador nulo faltando.
Para usá-la, inclua <string>. A classe fica no espaço de nomes std.
Esse operador + faz trabalho de verdade - ele aloca um buffer novo grande o suficiente para as duas partes e as copia para dentro. Com um char* cru você teria que recorrer a strcpy e strcat e torcer para que seu buffer fosse grande o bastante. std::string faz toda essa classe de erros desaparecer.
Montando e juntando strings
Você pode concatenar com +, mas o cavalo de batalha para fazer uma string crescer no lugar é +=. Ele anexa ao buffer existente em vez de produzir uma string totalmente nova a cada vez, o que faz diferença dentro de laços.
Uma surpresa comum: + exige que pelo menos um dos operandos já seja um std::string. Dois literais de string são apenas const char*, então "a" + "b" não compila - não existe um operator+ para dois ponteiros crus. Transforme um deles em string primeiro:
string s = "a" + "b"; // error: can't add two const char*
string s = string("a") + "b"; // fine - left side is a std::string
string s = "a"s + "b"; // fine in C++14+, the "s" literal suffix
Repare que essa última forma usa o sufixo s de <string> (using namespace std::string_literals;), que transforma um literal diretamente em um std::string.
Acessando o interior de uma string
Um std::string se comporta como um contêiner de char, então você pode indexá-lo, percorrê-lo e pedir pedaços dele.
substr(pos, len) retorna uma string totalmente nova copiada do original; ela não modifica a fonte. Cuidado com os limites: word[10] em uma string de 5 caracteres é comportamento indefinido - não vai lançar nada, apenas lê lixo. Se quiser um acesso verificado que lança std::out_of_range, use word.at(10) em vez de word[10].
Outra armadilha clássica: .size() retorna um tipo sem sinal (size_t). Escrever um laço de trás para frente como for (size_t i = word.size() - 1; i >= 0; --i) nunca termina, porque um i sem sinal nunca pode ficar abaixo de zero - ele dá a volta e vira um número enorme. Use um índice com sinal ou reestruture a condição quando precisar percorrer uma string ao contrário.
Buscando e substituindo
find localiza uma substring ou caractere e retorna o índice inicial. Quando o alvo não está presente, ele retorna a constante especial std::string::npos - sempre compare com ela em vez de presumir que find retorna -1.
Para mudar texto no lugar, replace(pos, len, text) troca um trecho por conteúdo novo (que pode ter outro tamanho), e insert/erase adicionam ou removem pedaços:
Strings e números
Texto e números não se convertem sozinhos - "42" são três caracteres, não o inteiro 42. A biblioteca padrão oferece funções de conversão nos dois sentidos. Use stoi, stod e companhia para analisar texto e transformá-lo em números, e to_string para ir na direção oposta.
Duas armadilhas aqui. Primeira, stoi("abc") lança std::invalid_argument, então proteja entrada não confiável com try/catch. Segunda, to_string(3.99) dá o 3.990000 completo - se você precisa de controle sobre precisão e formatação, isso é trabalho para string streams, que é exatamente para onde vamos a seguir.
try {
int n = std::stoi(userInput);
} catch (const std::invalid_argument&) {
std::cout << "That wasn't a number.\n";
}
A seguir: entrada e saída
Você vem imprimindo strings com cout esse tempo todo, mas lê-las de volta a partir do usuário tem suas próprias surpresas - cin >> name para no primeiro espaço, então uma linha inteira como "Ada Lovelace" precisa de std::getline. A próxima página cobre a entrada e saída em C++ como deve ser: operadores de stream, ler linhas inteiras e misturar >> com getline sem tropeçar em quebras de linha que sobraram.
Perguntas frequentes
Qual é a diferença entre std::string e char* em C++?
std::string é uma classe que possui e gerencia sua própria memória, cresce conforme necessário e se limpa automaticamente. Um char* é apenas um ponteiro cru para caracteres com um '\0' terminador - você gerencia o buffer, o tamanho e o tempo de vida por conta própria. Prefira std::string para quase tudo; ela elimina categorias inteiras de bugs de estouro de buffer e de ponteiro pendente.
Como obter o tamanho de uma string em C++?
Chame .size() ou seu apelido .length() em um std::string: name.size() retorna o número de caracteres como um size_t. Ambos retornam o mesmo valor; size() é o estilo mais comum porque combina com todos os outros contêineres da STL.
Como converter uma string em número em C++?
Use std::stoi para int, std::stod para double e semelhantes (stol, stof). Exemplo: int n = std::stoi("42");. Essas funções lançam std::invalid_argument se o texto não for um número, então envolva-as em um try/catch quando a entrada não for confiável.