Operações Fundamentais com std::string em C++

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;
}

Tags: C++ std::string string manipulation string operations lexicographical comparison

Publicado em 7-29 20:30