2012-10-04 18 views
6

Duplicar posibles:
how do I validate user input as a double in C++?C++, cómo verificar es la entrada de datos es del tipo de datos correcto

Soy nuevo en C++, y tengo una función en la que estoy queriendo que el usuario ingrese un valor de double. ¿Cómo podría asegurar que la entrada de valor era del tipo de datos correcto? Además, ¿cómo se manejaría un error? Por el momento esto es todo lo que tengo:

if(cin >> radius){}else{} 

que el uso de `try {} catch() {}, pero no creo que lo haría la solución adecuada para este problema. Cualquier ayuda sería apreciada.

+4

Esto funciona bastante bien: http://www.parashift.com/c++-faq/istream-and-ignore.html – chris

+1

leer como cadena y analizar el uso de expresiones regulares. – rplusg

Respuesta

13

Si ostream& operator>>(ostream& , T&) falla la extracción de datos formateados (como entero, doble, flotante, ...), stream.fail() será verdadero y por lo tanto !stream también se evaluará como verdadero.

Así que usted puede utilizar

cin >> radius; 
if(!cin){ 
    cout << "Bad value!"; 
    cin.clear(); 
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
    cin >> radius; 
} 

o simplemente

while(!(cin >> radius)){ 
    cout << "Bad value!"; 
    cin.clear(); 
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
} 

Es importante ignore el resto de la línea, ya que operator>> no extraerá los datos de la corriente más, ya que es en un formato incorrecto. Por lo tanto, si elimina

cin.ignore(numeric_limits<streamsize>::max(), '\n'); 

su bucle nunca terminará, ya que la entrada no se borra de la entrada estándar.

Consulte también:

+1

'sream.good()' puede ser falso incluso si la entrada es correcta. Y al usar la secuencia en un contexto booleano, falso es 'stream.fail()', y verdadero es '! Stream.fail()'; 'stream.good()' nunca entra en él. Cualquier referencia a 'istream :: good' con respecto al problema del póster es incorrecta. –

+3

Su afirmación de que 'operator >>' no extraerá ningún dato de la transmisión si no está en el formato correcto también es incorrecta; puede extraer _some_ de los datos. (Piense en una entrada a lo largo de las líneas de '" 1.2e + x "'.Las transmisiones solo garantizan la anticipación de un carácter, y el error no se puede detectar hasta que se vea el ''x''. Todos los personajes anteriores serán extraídos.) –

+0

@JamesKanze: Traté de encargarme de las preocupaciones en ambos comentarios, sin embargo, todavía se siente un poco torpe. Echaré un vistazo más adelante, si encuentra algún otro error, siéntase libre de editar y dejar un comentario. Siempre es bueno aprender algo nuevo :). – Zeta

3

Necesita leer toda la línea usando std::getline y std::string. Esa es la manera de verificar plenamente que toda la línea es del tipo de datos correcto:

std::string line; 
while(std::getline(std::cin, line)) 
{ 
    std::stringstream ss(line); 
    if ((ss >> radius) && ss.eof()) 
    { 
     // Okay break out of loop 
     break; 
    } 
    else 
    { 
     // Error! 
     std::cout << "Invalid input" << std::endl; 
    } 
} 
0

Este ejemplo se explica por sí mismo, sin embargo, con este método no se puede distinguir entre int y doble.

int main() 
{ 
    double number = 0; 

    if (!(std::cin >> number)) 
    { 
    std::cout << "That's not a number; "; 
    } 
    else 
    { 
    std::cout << "That's a number; "; 
    } 
} 
+2

Uhm Entonces, ¿y si entran, digamos, 0? ¿O es esto lo que no funciona con su parte? – StarWind0

Cuestiones relacionadas