2010-07-18 8 views
15

¿Cómo verificaría si la entrada es realmente un doble?¿cómo valido la entrada del usuario como un doble en C++?

double x; 

while (1) { 
    cout << '>'; 
    if (cin >> x) { 
     // valid number 
     break; 
    } else { 
     // not a valid number 
     cout << "Invalid Input! Please input a numerical value." << endl; 
    } 
} 
//do other stuff... 

El código anterior da salida a la declaración infinitamente Invalid Input!, así que no provocó una nueva respuesta. Quiero solicitar la entrada, verificar si es legítima ... si es un doble, continuar ... si NO es un doble, preguntar de nuevo.

¿Alguna idea?

+0

, asegúrese de buscar en la guía de formato próxima vez que hacer un post. Gracias. – strager

+0

¿qué quieres decir? ¿Qué hay de malo con el formateo? – Hristo

+0

Edité tu publicación, pero antes de la edición no se formateó el código. Haga clic en "editado hace N minutos" para ver la publicación original. – strager

Respuesta

14

Prueba esto:

while (1) { 
    if (cin >> x) { 
     // valid number 
     break; 
    } else { 
     // not a valid number 
     cout << "Invalid Input! Please input a numerical value." << endl; 
     cin.clear(); 
     while (cin.get() != '\n') ; // empty loop 
    } 
} 

Esto borra básicamente el estado de error, a continuación, lee y descarta todo lo que se ha introducido en la línea anterior.

+0

¿está esto dentro del bucle 'while (1)'? – Hristo

+0

Sí, dentro de su bucle existente. Acabo de reproducir la parte interna. – casablanca

+0

Ok eso funciona. ¿Puedes explicar la lógica detrás del bucle vacío? ¿Qué está pasando exactamente allí? ¿Qué hace 'get()' hacer? – Hristo

-3

Yo usaría scanf en lugar de cin.

La función scanf devolverá el número de coincidencias de la cadena de destino. Para asegurarse de que un doble válida se ha analizado, asegúrese de que el valor de retorno de scanf es 1.

Editar:
Cambiado fscanf a scanf.

+0

Quiero leer desde la línea de comandos ... no es 'fscanf' para leer desde un' FILE'? – Hristo

+0

La pregunta es acerca de cómo hacerlo usando 'cin'. – casablanca

+0

'scanf' proporcionará la misma funcionalidad, excepto que se leerá de' stdin' en lugar de un objeto de archivo arbitrario. – advait

1

failbit se configurará después de usar un operador de extracción si hubo un error de análisis, hay un par de funciones de prueba simples good y fail que puede verificar. Son exactamente lo opuesto porque manejan eofbit de manera diferente, pero eso no es un problema en este ejemplo.

Luego, tiene que borrar failbit antes de volver a intentarlo.

Como dice casablanca, también debe descartar los datos no numéricos que aún quedan en el búfer de entrada.

Así:

double x; 

while (1) { 
    cout << '>'; 
    cin >> x; 
    if (cin.good()) 
     // valid number 
     break; 
    } else { 
     // not a valid number 
     cout << "Invalid Input! Please input a numerical value." << endl; 
     cin.clear(); 
     cin.ignore(100000, '\n'); 
    } 
} 
//do other stuff... 
+0

, esto todavía está causando que el bucle infinito imprima 'Invalid Input!' ... no está pidiendo otra entrada. – Hristo

+0

¿Qué hace el 'cin.ignore()' hacer? – Hristo

+0

Lo mismo que el bucle de casablanca, descarta todos los caracteres hasta la línea nueva incluida para deshacerse de los datos no numéricos que causaron la falla de la primera extracción. –

0

Una forma es verificar la igualdad de números flotantes.

double x; 

while (1) { 
    cout << '>'; 
    cin >> x; 
    if (x != int(x)) { 
     // valid number 
     break; 
    } else { 
     // not a valid number 
     cout << "Invalid Input! Please input a numerical value." << endl; 
    } 
} 
+0

¿Cómo se comprueba esto para el tipo 'double'? – Hristo

+0

Esto solo comprueba si la entrada tiene una parte fraccionaria, que probablemente no es lo que se entiende por la pregunta. –

+0

Sí, la mayoría de nosotros sabe a qué se refería Hristo, pero esta respuesta responde a la pregunta que hizo: "¿Cómo verificaría si la entrada es realmente doble?" Interpretando eso como "Supongo que obtengo números, ¿cómo me aseguro de que no sean números enteros?" hace de esto una respuesta perfectamente útil. No hay necesidad de downvote, imo. – chaosTechnician

0
#include <iostream> 
#include <string> 

bool askForDouble(char const *question, double &ret) 
{ 
     using namespace std; 
     while(true) 
     { 
       cout << question << flush; 
       cin >> ret; 
       if(cin.good()) 
       { 
         return true; 
       } 
       if(cin.eof()) 
       { 
         return false; 
       } 
       // (cin.fail() || cin.bad()) is true here 
       cin.clear(); // clear state flags 
       string dummy; 
       cin >> dummy; // discard a word 
     } 
} 

int main() 
{ 
     double x; 
     if(askForDouble("Give me a floating point number! ",x)) 
     { 
       std::cout << "The double of it is: " << (x*2) << std::endl; 
     } else 
     { 
       std::cerr << "END OF INPUT" << std::endl; 
     } 
     return 0; 
} 
+1

La validación de entrada debería haber sido una tarea más fácil de hacer. Hace que sea muy difícil enseñar a los novatos y ayudarlos a disfrutar de lo que están haciendo. Me gustaría ver un tutorial a prueba de balas y todavía útil sobre cin y cout para principiantes. – Notinlist

0
bool is_double(double val) 
{ 
bool answer; 
double chk; 
int double_equl = 0;  
double strdouble = 0.0; 
strdouble = val;   
double_equl = (int)val; 
chk = double_equl/strdouble; 
if (chk == 1.00) 
{ 
answer = false; // val is integer 
return answer; 
} else { 
answer = true; // val is double 
return answer; 
} 
} 
Cuestiones relacionadas