Desafio C++

Conversor seguro de string para número

Enunciado

Leia uma linha e tente convertê-la para int. Se for válida, imprima o dobro; caso contrário, imprima invalido. Use std::stoi com tratamento de exceções.

Requisitos

  • Usar std::stoi dentro de um bloco try.
  • Capturar std::invalid_argument e std::out_of_range.
  • Imprimir o dobro do número ou a palavra invalido.

Código inicial

#include <iostream>
#include <string>
#include <stdexcept>

int main() {
    std::string linha;
    std::getline(std::cin, linha);
    // TODO: converta com stoi e trate exceções
    return 0;
}

Saída esperada

84
Ver dica

std::stoi lança exceções; use try/catch para capturá-las e imprimir invalido.

Mostrar solução
#include <iostream>
#include <string>
#include <stdexcept>

int main() {
    std::string linha;
    std::getline(std::cin, linha);

    try {
        int valor = std::stoi(linha);   // pode lançar exceção
        std::cout << valor * 2 << '\n';
    } catch (const std::invalid_argument&) {
        std::cout << "invalido\n";      // texto não numérico
    } catch (const std::out_of_range&) {
        std::cout << "invalido\n";      // número fora do intervalo de int
    }

    return 0;
}

Passo a passo

  1. Lemos a linha inteira com getline para não perder caracteres.
  2. Dentro do try, chamamos std::stoi(linha), que converte a string em int.
  3. Se a conversão der certo, imprimimos valor * 2.
  4. Se a string não for numérica, std::invalid_argument é lançada e capturada, imprimindo invalido.
  5. Se o número for grande demais para int, std::out_of_range é capturada e também imprimimos invalido.

Por que funciona

std::stoi valida e converte; quando falha, lança exceções específicas. Capturando ambas, cobrimos os dois modos de erro sem encerrar o programa.

Erros comuns

  • Não capturar exceções: o programa aborta com mensagem de erro.
  • Capturar apenas std::exception: funciona, mas perde a distinção entre os erros.
  • Usar std::stoi em string vazia: lança std::invalid_argument; nosso catch trata.

Outra forma de resolver

Usar std::from_chars (C++17) para conversão sem exceções:

#include <charconv>
int valor;
auto [ptr, ec] = std::from_chars(linha.data(), linha.data() + linha.size(), valor);
if (ec == std::errc() && ptr == linha.data() + linha.size())
    std::cout << valor * 2 << '\n';
else
    std::cout << "invalido\n";

Saída esperada

84