c ++ getline () no está esperando la entrada de la consola cuando se le llama varias veces

Estoy intentando obtener algunos parámetros de entrada de usuario desde la consola, dos cadenas, dos entradas y un doble. El código relevante que estoy tratando de usar es este:

#include  #include  using namespace std; // ... string inputString; unsigned int inputUInt; double inputDouble; // ... cout << "Title: "; getline(cin, inputString); tempDVD.setTitle(inputString); cout << "Category: "; getline(cin, inputString); tempDVD.setCategory(inputString); cout <> inputUInt; tempDVD.setDuration(inputUInt); cout <> inputUInt; tempDVD.setYear(inputUInt); cout <> inputDouble; tempDVD.setPrice(inputDouble); 

Sin embargo, al ejecutar el progtwig, en lugar de esperar a que se ingrese la primera cadena de entrada, el código no se detiene hasta la segunda llamada a getline (). Por lo tanto, la salida de la consola se ve así:

Título: Categoría:

con el cursor apareciendo después de la categoría. Si ingreso ahora, el progtwig salta a la entrada del año y no me permite ingresar más de una cadena. ¿Que esta pasando aqui?

El problema es que estás mezclando llamadas a getline () con el uso del operador >>.

Recuerde que el operador >> ignoró el espacio en blanco inicial, por lo que continuará correctamente a través de los límites de las líneas. Pero deja de leer después de que la entrada se ha recuperado correctamente y, por lo tanto, no se traga los caracteres ‘\ n’ posteriores. Por lo tanto, si usas getline () después de >> normalmente obtienes lo incorrecto a menos que seas cuidadoso (para eliminar primero el carácter ‘\ n’ que no fue leído).

El truco es no usar ambos tipos de entrada. Elija el adecuado y quédese con él.

Si se trata de todos los números (u objetos que funcionan bien con el operador >>), simplemente utilice el operador >> (La cadena de notas es el único tipo fundamental que no es simétrico con la entrada / salida (es decir, no funciona bien)).

Si la entrada contiene cadenas o una combinación de elementos que requerirán getline (), entonces solo use getline () y analice el número de la cadena.

 std::getline(std::cin, line); std::stringstream linestream(line); int value; linestream >> value; // Or if you have boost: std::getline(std::cin, line); int value = boost::lexical_cast(line); 

Necesita enjuagar el buffer de entrada. Se puede hacer con cin.clear(); cin.sync(); cin.clear(); cin.sync(); .

Puedes usar

 cin.ignore(); 

o como @kernald mencionó el uso

 cin.clear(); cin.sync(); 

antes de usar getline ()

Use cin.clear() como se menciona y use el manejo adecuado de errores:

  cin.clear(); cin.sync(); cout << "Title: "; if (!getline(cin, inputString)) exit 255; tempDVD.setTitle(inputString); cout << "Category: "; if (!getline(cin, inputString)) exit 255; tempDVD.setCategory(inputString); cout << "Duration (minutes): "; if (!(cin >> inputUInt)) exit 255; tempDVD.setDuration(inputUInt); cout << "Year: "; if (!(cin >> inputUInt)) exit 255; tempDVD.setYear(inputUInt); cout << "Price: $"; if (!(cin >> inputDouble)) exit 255; tempDVD.setPrice(inputDouble); 

Mezclar getline () con flujos de entrada en general es algo malo que hacer. Teóricamente es posible manejar manualmente los búferes sucios que quedan con las transmisiones, pero es un dolor innecesario que definitivamente debe evitarse.

Es mejor utilizar una biblioteca de consola para obtener su entrada, de esta manera el trabajo sucio puede abstraerse para usted.

Eche un vistazo a TinyCon. Puede usar el método estático tinyConsole :: getLine () para reemplazar sus llamadas a getline y stream, y puede usarlo tantas veces como desee.

Puede encontrar información aquí: https://sourceforge.net/projects/tinycon/

cin.sync (); usa esto en lugar de cin.ignore (funciona mejor)