with sirve que para ejemplos c++ stream cin

c++ - sirve - std::cout



cin>> error en la entrada con símbolo+ (3)

Creo que >> piensa que está comenzando otro entero con +/-. Luego se enoja cuando no sigues con los dígitos.

Como dijo @ Robᵩ, dijo una cadena y el elenco. Solo ofrecería otra opción de la biblioteca estándar:

int stoi(const string& str, size_t *idx = 0, int base = 10);

Esto arroja invalid_argument si no se puede realizar ninguna conversión o out_of_range si el valor convertido está fuera del rango de valores representables para el tipo de devolución.

Esto es de The Standard.

En un programa C ++ estoy tratando de procesar la entrada del usuario que consiste en operandos enteros intercalados con operadores (+ - / *). Tengo el lujo de exigirles a los usuarios que pongan espacios en blanco antes y después de cada operador. Mi enfoque es suponer que cualquier cosa que no sea int es un operador. Así que, tan pronto como haya un error no electrónico en la transmisión, invoco cin.clear () y leo el siguiente valor en una cadena.

#include <iostream> #include <string> //in some other .cpp i have these functions defined void process_operand(int); void process_operator(string); using namespace std; int main() { int oprnd; string oprtr; for (;; ) { while ( cin >> oprnd) process_operand(oprnd); if (cin.eof()) break; cin.clear(); cin >> oprtr; process_operator(oprtr); } }

Esto funciona bien para los operadores / y * pero no para los operadores + -. El motivo es que el operator>> consume el signo + o - antes de informar el error y no lo vuelve a poner en el flujo. Entonces obtengo una lectura de token inválida en oprtr.

Ex: 5 1 * 2 4 6 * / works fine 5 1 + 2 ^ ---> 2 becomes the oprnd here.

¿Cuál sería una buena forma de C ++ para lidiar con este problema?


Lee en std::string s y boost::lexical_cast<> usando boost::lexical_cast<> o su equivalente.

int main() { string token; while ( cin >> token) { try { process_operand(boost::lexical_cast<int>(token)); } catch (std::bad_cast& e) { process_operator(token); } } }

Posdata : si eres alérgico a Boost, puedes usar esta implementación de lexical_cast:

template <class T, class U> T lexical_cast(const U& u) { T t; std::stringstream s; s << u; s >> t; if( !s ) throw std::bad_cast(); if( s.get() != std::stringstream::traits_type::eof() ) throw std::bad_cast(); return t; }


No se conoce la forma en C ++, pero la forma de C sería leer en cadenas y usar atoi para convertir a enteros.