Introdução à Manipulação de Strings com std::string
A classe std::string em C++ é uma ferramenta essencial para o gerenciamento de sequências de caracteres. Ela oferece uma abstração mais segura e flexível em comparação com os arrays de caracteres estilo C (C-strings), pois lida automaticamente com a alocação e desalocação de memória. Este artigo aborda as operações mais comuns e importantes para manipular objetos std::string.
Declaração e Inicialização de std::string
Um objeto std::string pode ser declarado e inicializado de diversas formas, atendendo a diferentes cenários:
#include <iostream>
#include <string> // Necessário para std::string
int main() {
// 1. Declaração de uma string vazia
std::string nomeUsuario;
std::cout << "String vazia (nomeUsuario): '" << nomeUsuario << "'\n";
// 2. Inicialização com um literal de string
std::string saudacao = "Olá, Programador C++!";
std::cout << "Saudação: '" << saudacao << "'\n";
// 3. Inicialização por cópia de outra string
std::string copiaSaudacao = saudacao;
std::cout << "Cópia da saudação: '" << copiaSaudacao << "'\n";
// 4. Inicialização com N caracteres repetidos
std::string tracos(10, '-'); // Uma string com 10 traços
std::cout << "Linha de traços: '" << tracos << "'\n";
// 5. Inicialização a partir de um C-string
const char* tituloC = "Fundamentos de C++";
std::string tituloString = tituloC;
std::cout << "Título como string: '" << tituloString << "'\n";
return 0;
}
Obtenção do Tamanho da String
Para determinar o número de caracteres em uma string, as funções membros length() e size() são empregadas. Para std::string, ambas são equivalentes e retornam um valor do tipo std::string::size_type, que é um tipo inteiro sem sinal. Recomenda-se usar size_type ao lidar com tamanhos e índices para garantir a compatibilidade e evitar problemas de conversão.
#include <iostream>
#include <string>
int main() {
std::string fraseExemplo = "Este é um texto de teste.";
std::string::size_type numCharsLength = fraseExemplo.length();
std::string::size_type numCharsSize = fraseExemplo.size();
std::cout << "Frase: '" << fraseExemplo << "'\n";
std::cout << "Número de caracteres (length()): " << numCharsLength << "\n"; // Saída: 25
std::cout << "Número de caracteres (size()): " << numCharsSize << "\n"; // Saída: 25
return 0;
}
Localizando Substrings
O método find() permite localizar a primeira ocorrência de uma substring dentro de uma string. Ele retorna a posição (índice baseado em zero) do primiero caractere da substring encontrada. Caso a substring não seja encontrada, find() retorna std::string::npos, uma constante que indica "não encontrado" e que possui o valor máximo para std::string::size_type.
#include <iostream>
#include <string>
int main() {
std::string textoCompleto = "Aprender C++ é uma jornada gratificante.";
std::string termoBuscar1 = "jornada";
std::string termoBuscar2 = "desafio"; // Este termo não está no texto
std::string::size_type posicao1 = textoCompleto.find(termoBuscar1);
if (posicao1 != std::string::npos) {
std::cout << "Termo '" << termoBuscar1 << "' encontrado na posição: " << posicao1 << "\n"; // Saída: 19
} else {
std::cout << "Termo '" << termoBuscar1 << "' não encontrado.\n";
}
std::string::size_type posicao2 = textoCompleto.find(termoBuscar2);
if (posicao2 != std::string::npos) {
std::cout << "Termo '" << termoBuscar2 << "' encontrado na posição: " << posicao2 << "\n";
} else {
std::cout << "Termo '" << termoBuscar2 << "' não encontrado.\n"; // Saída: 'desafio' não encontrado.
}
return 0;
}
Concatenação de Strings
A concatenação (união) de strings pode ser realizada usando o operador de adição (+) ou o método append().
#include <iostream>
#include <string>
int main() {
std::string prefixo = "Bom ";
std::string sufixo = "dia!";
std::string complemento = "Tenha um ótimo ";
// Concatenação com o operador '+'
std::string cumprimento1 = prefixo + sufixo;
std::cout << "Cumprimento 1: " << cumprimento1 << "\n"; // Saída: Bom dia!
// O operador '+' suporta concatenação com literais char e C-strings
std::string cumprimentoCompleto = complemento + prefixo + sufixo + ' ' + "para todos.";
std::cout << "Cumprimento completo: " << cumprimentoCompleto << "\n"; // Saída: Tenha um ótimo Bom dia! para todos.
// Concatenação com o método append()
std::string construcaoFrase = "Isso ";
construcaoFrase.append("é ");
construcaoFrase.append("uma ");
construcaoFrase.append("string ");
construcaoFrase.append("construída ");
construcaoFrase.append("com append.");
std::cout << "Frase com append: " << construcaoFrase << "\n"; // Saída: Isso é uma string construída com append.
// append() pode adicionar caracteres específicos ou partes de outras strings
std::string dados = "Dados";
dados.append(1, ':').append(1, ' ').append("informações importantes."); // Adiciona ':' e um espaço
std::cout << "Dados formatados: " << dados << "\n"; // Saída: Dados: informações importantes.
return 0;
}
Substituição de Conteúdo em Strings
O método replace() permite substituir uma parte específica de uma string por outra string. Ele requer três argumentos principais: a posição inicial da substituição, o número de caracteres a serem substituídos e a string que será inserida no lugar.
#include <iostream>
#include <string>
int main() {
std::string textoOriginal = "O resultado é satisfatório e agradável.";
std::cout << "Original: " << textoOriginal << "\n";
// Substituir "satisfatório" por "excelente"
// "satisfatório" começa na posição 14 e tem 12 caracteres
textoOriginal.replace(14, 12, "excelente");
std::cout << "Após substituição 1: " << textoOriginal << "\n"; // Saída: O resultado é excelente e agradável.
// Substituir "agradável" por "perfeito"
// "agradável" começa na posição 27 e tem 9 caracteres
textoOriginal.replace(27, 9, "perfeito");
std::cout << "Após substituição 2: " << textoOriginal << "\n"; // Saída: O resultado é excelente e perfeito.
return 0;
}
Extração de Substrings
O método substr() é utilizado para extrair uma porção de uma string existente. Ele aceita dois argumentos: a posição inicial (índice do primeiro caractere a ser incluído) e, opcionalmente, o comprimento da substring a ser extraída. Se o comprimento for omitido, substr() extrairá caracteres desde a posição inicial até o final da string.
#include <iostream>
#include <string>
int main() {
std::string urlCompleta = "https://www.exemplo.com/path/para/recurso.html";
std::cout << "URL completa: " << urlCompleta << "\n";
// Extrair o protocolo (inicia na pos 0, tem 5 caracteres)
std::string protocolo = urlCompleta.substr(0, 5);
std::cout << "Protocolo: " << protocolo << "\n"; // Saída: https
// Extrair o domínio (inicia na pos 12, tem 11 caracteres)
std::string dominio = urlCompleta.substr(12, 11);
std::cout << "Domínio: " << dominio << "\n"; // Saída: exemplo.com
// Extrair o caminho completo (inicia na pos 24, até o final)
std::string caminho = urlCompleta.substr(24);
std::cout << "Caminho: " << caminho << "\n"; // Saída: /path/para/recurso.html
return 0;
}
Comparação de Strings
std::string pode ser comparada de duas maneiras principais: através do método membro compare() ou utilizando os operadores de comparação (==, !=, <, >, <=, >=).
Método compare()
O método compare() realiza uma comparação lexicográfica entre duas strings e retorna um valor inteiro:
0: As strings são idênticas.- Um valor negativo: A string que invoca o método é lexicograficamente mener que a string passada como argumento.
- Um valor positivo: A string que invoca o método é lexicograficamente maior que a string passada como argumento.
#include <iostream>
#include <string>
int main() {
std::string item1 = "maçã";
std::string item2 = "laranja";
std::string item3 = "maçã";
int compResult1 = item1.compare(item2); // 'm' > 'l' se considerar o ASCII, mas lexicograficamente 'maçã' < 'laranja' porque 'l' vem antes de 'm'
// na verdade, 'l' antes de 'm', então 'laranja' < 'maçã', e item1.compare(item2) será positivo!
// CORREÇÃO: 'm' > 'l' é o que acontece. item1 (maçã) é maior que item2 (laranja)
// 'm' ASCII 109, 'l' ASCII 108.
// Portanto, item1 > item2, resultando em um valor POSITIVO.
int compResult2 = item1.compare(item3); // "maçã" == "maçã"
int compResult3 = item2.compare(item1); // 'l' < 'm'. item2 (laranja) é menor que item1 (maçã).
// Portanto, item2 < item1, resultando em um valor NEGATIVO.
std::cout << "Comparando '" << item1 << "' com '" << item2 << "': " << compResult1 << " (Positivo se item1 > item2)\n";
std::cout << "Comparando '" << item1 << "' com '" << item3 << "': " << compResult2 << " (Zero se item1 == item3)\n";
std::cout << "Comparando '" << item2 << "' com '" << item1 << "': " << compResult3 << " (Negativo se item2 < item1)\n";
return 0;
}
Operadores de Comparação
Os operadores sobrecarregados (==, !=, <, >, <=, >=) fornecem uma maneira mais idiomática e legível de comparar strings em C++. Eles também realizam uma comparação lexicográfica.
#include <iostream>
#include <string>
int main() {
std::string termoA = "caminho";
std::string termoB = "caminho";
std::string termoC = "diretório";
std::cout << "'" << termoA << "' == '" << termoB << "': " << (termoA == termoB ? "Verdadeiro" : "Falso") << "\n"; // Verdadeiro
std::cout << "'" << termoA << "' != '" << termoC << "': " << (termoA != termoC ? "Verdadeiro" : "Falso") << "\n"; // Verdadeiro
std::cout << "'" << termoA << "' < '" << termoC << "': " << (termoA < termoC ? "Verdadeiro" : "Falso") << "\n"; // Verdadeiro ('c' < 'd')
std::cout << "'" << termoC << "' > '" << termoA << "': " << (termoC > termoA ? "Verdadeiro" : "Falso") << "\n"; // Verdadeiro ('d' > 'c')
std::cout << "'" << termoA << "' <= '" << termoB << "': " << (termoA <= termoB ? "Verdadeiro" : "Falso") << "\n"; // Verdadeiro
return 0;
}