Transformando std::string em int: batalha de desempenho e conveniência em C++

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: A eterna questão "std::string para int"

\n\n

Olá, colega programador! Se você já escreveu em C++ um parser de configurações, processou entrada do usuário ou extraiu números de um arquivo CSV, certamente já enfrentou a tarefa: "Como transformar uma string comum (std::string) em um número inteiro (int)?". Parece simples, não é? No entanto, ao olhar no Stack Overflow, você verá milhares de votos e dezenas de respostas diferentes. Por quê? Porque por trás dessa pergunta simples existe um mundo de compromissos entre conveniência, segurança e desempenho.

\n\n

Neste artigo, não vamos dar apenas uma resposta seca. Vamos promover uma verdadeira batalha entre os principais métodos de conversão: std::stoi, std::from_chars (C++17), std::stringstream, o bom e velho atoi e até mesmo criar nossa própria solução caseira. Você descobrirá qual método escolher para um servidor de alta carga e qual usar para um protótipo rápido. Vamos nessa!

\n\n

Método 1: O clássico — std::stoi (C++11)

\n\n

A partir do C++11, a biblioteca padrão ganhou a elegante função std::stoi. Ela é simples, legível e lança exceções em caso de erros. É a escolha de 90% dos desenvolvedores para tarefas do dia a dia.

\n\n
#include <iostream>\n#include <string>\n\nint main() {\n    std::string number_str = "12345";\n    try {\n        int value = std::stoi(number_str);\n        std::cout << "Número: " << value << std::endl;\n    } catch (const std::invalid_argument& e) {\n        std::cerr << "Erro: a string não contém um número!" << std::endl;\n    } catch (const std::out_of_range& e) {\n        std::cerr << "Erro: o número está fora dos limites do int!" << std::endl;\n    }\n    return 0;\n}
\n\n

Prós e contras do std::stoi

\n
    \n
  • Prós: Simplicidade, suporte a locales (reconhece vírgulas como separadores), tratamento automático de erros via exceções.
  • \n
  • Contras: Exceções são caras. Se você estiver parseando milhões de números em um loop, o try-catch pode desacelerar significativamente o código.
  • \n
\n\n

Método 2: Mais rápido que o vento — std::from_chars (C++17)

\n\n

Se você está escrevendo uma aplicação de alta carga, onde cada nanossegundo conta, então std::from_chars é seu herói. Esta função não aloca memória, não lança exceções e não depende de locale. Ela simplesmente converte caracteres em um número e retorna um ponteiro para o ponto de parada.

\n\n
#include <iostream>\n#include <charconv>\n#include <string>\n#include <system_error>\n\nint main() {\n    std::string number_str = "98765";\n    int value = 0;\n    auto [ptr, ec] = std::from_chars(number_str.data(), \n                                      number_str.data() + number_str.size(), \n                                      value);\n    if (ec == std::errc()) {\n        std::cout << "Número: " << value << std::endl;\n    } else {\n        std::cerr << "Erro de conversão!" << std::endl;\n    }\n    return 0;\n}
\n\n

Por que from_chars é o rei do desempenho?

\n
    \n
  • Zero-overhead: Sem exceções, sem alocações ocultas.
  • \n
  • Localização desativada: Não há necessidade de perder tempo verificando separadores decimais.
  • \n
  • Retorna o restante da string: Ideal para parsing de colunas em CSV.
  • \n
\n

De acordo com benchmarks, from_chars pode ser de 2 a 10 vezes mais rápido que stoi, especialmente em strings curtas.

\n\n

Método 3: Artilharia pesada — std::stringstream

\n\n

Muitos programadores iniciantes usam std::stringstream para conversão. É uma ferramenta poderosa, mas para a tarefa "string para número", ela é exagerada, como um tanque para ir ao mercado comprar pão.

\n\n
#include <sstream>\n#include <string>\n#                

Blogs

Book Recommendations