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::stoidentro de um blocotry. - Capturar
std::invalid_argumentestd::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
- Lemos a linha inteira com
getlinepara não perder caracteres. - Dentro do
try, chamamosstd::stoi(linha), que converte a string emint. - Se a conversão der certo, imprimimos
valor * 2. - Se a string não for numérica,
std::invalid_argumenté lançada e capturada, imprimindoinvalido. - Se o número for grande demais para
int,std::out_of_rangeé capturada e também imprimimosinvalido.
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::stoiem string vazia: lançastd::invalid_argument; nossocatchtrata.
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