Usando getline(cin, s) después de cin [duplicado]

Resuelto pauliwago asked hace 13 años • 13 respuestas

Necesito el siguiente programa para tomar la línea completa 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 cin >> numbercomando antes del getline()comando (que supongo que es el problema), no me permite ingresar nombres. ¿Por qué?

Escuché algo sobre un cin.clear()comando, pero no tengo idea de cómo funciona o por qué es necesario.

pauliwago avatar Apr 21 '11 12:04 pauliwago
Aceptado
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);
Cristiano Miranda avatar Jul 08 '2012 19:07 Cristiano Miranda

Otra forma de hacerlo es poner un

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

después cin>>number;de vaciar el búfer de entrada por completo (rechazando todos los caracteres adicionales hasta que se encuentre una nueva línea). Necesitas #include <limits>obtener el max()método.

jonsca avatar Apr 21 '2011 05:04 jonsca
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 utilizar simplemente ignorar?

Esto es bastante detallado, por lo que usarlo ignoreen la secuencia posterior >> xes una forma alternativa muy recomendada de descartar contenido hasta la siguiente nueva línea, pero corre el riesgo de descartar contenido que no sea un espacio en blanco y, al hacerlo, pasar por alto datos corruptos en el archivo. Puede que le importe o no, dependiendo de si el contenido del archivo es confiable, de qué tan importante es evitar el procesamiento de datos corruptos, etc.

Entonces, ¿cuándo usarías borrar e ignorar?

Por lo tanto, std::cin.clear()(y std::cin.ignore()) 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 sencillo con skipws o similar?

Otra alternativa simple pero a medias ignorepara su requisito original es usar std::skipwspara omitir cualquier cantidad de espacios en blanco antes de leer las líneas...

if (std::cin >> number >> std::skipws)
{
    while (getline(std::cin, name))
        ...

...pero si recibe una entrada como "1E6" (por ejemplo, un científico que intenta ingresar 1.000.000 pero C++ solo admite esa notación para números de coma flotante) no acepta eso, terminaría con numberset to 1y E6se leería como primer valor de name. Por otra parte, si tuviera un número válido seguido de una o más líneas en blanco, esas líneas se ignorarían silenciosamente.

Tony Delroy avatar Apr 21 '2011 05:04 Tony Delroy