c++ - while - Usando getline(cin, s) después de cin
getline(cin variable) (12)
Conceptualmente, creo que quiere que cada respuesta sea claramente una línea. Entonces, ¿por qué no pruebas esto?
cout << "Enter the number: ";
string line;
getline(cin, line);
int number = std::stoi(line);
cout << "Enter names: ";
string names;
getline(cin, names);
El código consume correctamente el primer carácter de nueva línea, le proporciona el número si la línea es correcta o arroja una excepción si no lo está. Todo gratis!
Necesito el siguiente programa para tomar toda la línea de entrada del usuario y ponerla en nombres de cadena:
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
getline(cin, names);
Sin embargo, con el comando cin >> number
antes del comando getline()
(que supongo que es el problema), no me permitirá ingresar nombres. ¿Por qué?
Escuché algo sobre un cin.clear()
, pero no tengo idea de cómo funciona esto o por qué es necesario.
O puede vaciar el búfer de entrada para leer la cadena
fflush (stdin)
se define en el encabezado stdio.h .
Este código funciona ...
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
fflush(stdin); //FLUSHING STDIN
getline(cin, names);
Otra forma de hacerlo es poner un
cin.ignore ( std::numeric_limits<std::streamsize>::max(), ''/n'' );
después de tu cin>>number;
para vaciar el buffer de entrada por completo (rechazando todos los caracteres extra hasta que se encuentre una nueva línea). Necesita #include <limits>
para obtener el método max()
.
Puede encontrar la respuesta que desea en cppreference .
Cuando se usa inmediatamente después de la entrada delimitada por espacios en blanco, p. Ej. Después de
int n; std::cin >> n;
int n; std::cin >> n;
, getline consume el carácter de la línea final que queda en el flujo de entrada por el operador >>, y lo devuelve inmediatamente. Una solución común es ignorar todos los caracteres sobrantes en la línea de entrada concin.ignore(std::numeric_limits<std::streamsize>::max(), ''/n'');
antes de cambiar a la entrada orientada a la línea.
Puede usar std :: ws para extraer los caracteres en blanco en el búfer de entrada antes de usar getline. El encabezado de std :: ws es sstream.
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
cin>>ws;
getline(cin, names);
Tratar:
int number;
cin >> number;
char firstCharacterOfNames;
cin >> firstCharacterOfNames; // This will discard all leading white space.
// including new-line if there happen to be any.
cin.unget(); // Put back the first character of the name.
std::string names;
std::getline(cin, names); // Read the names;
Alternativamente. Si sabes que el número y los nombres siempre estarán en líneas diferentes.
cin >> number;
cin.ignore(std::numeric_limits<std::streamsize>::max(), ''/n'');
std::getline(cin, names);
acabo de usar
getline(cin >> ws,lard.i_npute);
con el estándar
#include <iostream>
encabezado en las instancias en las que tuve problemas con los retornos de carro y el manipulador ws funcionó. Probablemente comenzaré a incorporar funciones de bucle como clases y usaré al menos las llamadas de constructor y destructor.
desea utilizar cin.ignore () después de sus declaraciones cin porque quiere ignorar el "/ n" que queda en el búfer después de tomar su variable int con cin.
Tengo un programa similar que utilicé con un problema similar:
#include <iostream>
#include <iomanip>
#include <limits>
using namespace std;
int main() {
int i = 4;
double d = 4.0;
string s = "HackerRank ";
// Declare second integer, double, and String variables.
int n;
double d2;
string str;
// Read and save an integer, double, and String to your variables.
cin >> n;
cin >> d2;
cin.ignore();
getline(cin, str);
// Print the sum of both integer variables on a new line.
cout << i + n << endl;
// Print the sum of the double variables on a new line.
cout << d + d2 << endl;
// Concatenate and print the String variables on a new line
cout << s << str << endl;
// The ''s'' variable above should be printed first.
return 0;
}
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
// USE peek() TO SOLVE IT! ;)
if (cin.peek() == ''/n'') {
cin.ignore(1 /*numeric_limits<streamsize>::max()*/, ''/n'');
}
getline(cin, names);
return 0;
}
Solo cin.peek()
hacia adelante utilizando cin.peek()
y vea si aún queda ''/n''
en el búfer interno de cin
. Si es así: ignóralo (básicamente omítalo)
cout << "Enter the number: ";
int number;
cin >> number;
cin.ignore(256, ''/n''); // remaining input characters up to the next newline character
// are ignored
cout << "Enter names: ";
string names;
getline(cin, names);
cout << "Enter the number: ";
int number;
cin >> number;
cout << "Enter names: ";
string names;
getline(cin, names);//works on the /n left behind
getline(cin, names);//continues and rewrites names
Es bastante explicativo, hay un / n dejado atrás en la secuencia que utiliza el cin >> number
, que se asigna a los nombres la primera vez que se usa. Reutilizando getline escribe el valor correcto ahora.
cout << "Enter the number: ";
int number;
if (cin >> number)
{
// throw away the rest of the line
char c;
while (cin.get(c) && c != ''/n'')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character ''" << c << "'' found/n";
exit(EXIT_FAILURE);
}
cout << "Enter names: ";
string name;
// keep getting lines until EOF (or "bad" e.g. error reading redirected file)...
while (getline(cin, name))
...use name...
}
else
{
std::cerr << "ERROR reading number/n";
exit(EXIT_FAILURE);
}
En el código anterior, este bit ...
char c;
while (cin.get(c) && c != ''/n'')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character ''" << c << "'' found/n";
exit(EXIT_FAILURE);
}
... comprueba el resto de la línea de entrada después de que el número contenga solo espacios en blanco.
¿Por qué no usar simplemente ignorar?
Eso es bastante detallado, por lo que usar ignore
en la transmisión después de >> x
es una manera alternativa muy recomendable para descartar contenido hasta la próxima línea nueva, pero se corre el riesgo de descartar el contenido no en blanco y al hacerlo, pasar por alto los datos corruptos en el archivo . Puede que le importe o no, dependiendo de si el contenido del archivo es confiable, qué tan importante es evitar el procesamiento de datos corruptos, etc.
Entonces, ¿cuándo usarías clear e ignorarías?
Por lo tanto, std::cin.clear()
(y std::cin.igore()
) no es necesario para esto, pero es útil para eliminar el estado de error. Por ejemplo, si desea darle al usuario muchas oportunidades para ingresar un número válido.
int x;
while (std::cout << "Enter a number: " &&
!(std::cin >> x))
{
if (std::cin.eof())
{
std::cerr << "ERROR unexpected EOF/n";
exit(EXIT_FAILURE);
}
std::cin.clear(); // clear bad/fail/eof flags
// have to ignore non-numeric character that caused cin >> x to
// fail or there''s no chance of it working next time; for "cin" it''s
// common to remove the entire suspect line and re-prompt the user for
// input.
std::cin.ignore(std::numeric_limits<std::streamsize>::max());
}
¿No puede ser más simple con skipws o similar?
Otra alternativa simple pero a medias a ignore
para su requisito original es usar std::skipws
para saltear cualquier cantidad de espacio en blanco antes de leer líneas ...
if (std::cin >> number >> std::skipws)
{
while (getline(std::cin, name))
...
... pero si recibe información como "1E6" (por ejemplo, algunos científicos intentan ingresar 1.000.000 pero C ++ solo admite esa notación para números de coma flotante) no aceptarán eso, terminarían con el number
establecido en 1
, y E6
leer como el primer valor del name
. Por separado, si tuviera un número válido seguido de una o más líneas en blanco, esas líneas serían ignoradas en silencio.