Menu

Entrada y salida en C++: cin, cout, getline y streams

Cómo funciona la E/S por consola en C++: imprimir con cout, leer con cin, el clásico error del salto de línea con getline tras cin y cómo recuperarte cuando la entrada falla.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Cómo se comunica C++ con la consola

C++ realiza la E/S por consola mediante streams de la cabecera <iostream>. Escribes al mundo con cout (salida de caracteres) y lees del usuario con cin (entrada de caracteres). Usan dos operadores que ya has visto como desplazamientos de bits, reutilizados aquí:

  • << es el operador de inserción: envía datos hacia cout.
  • >> es el operador de extracción: saca datos de cin hacia una variable.

Una forma fácil de recordar la dirección: las flechas apuntan en el sentido en que fluyen los datos. Ahora que puedes guardar texto en cadenas, vamos a mover ese texto dentro y fuera de tu programa.

Imprimir con cout

cout envía a la salida estándar todo lo que insertes. Puedes encadenar varios << en una sola sentencia, mezclando libremente texto, números y variables.

Cada << se añade a la misma línea hasta que insertas un salto de línea. Tienes dos maneras de hacerlo: '\n' inserta un carácter de salto de línea, mientras que endl inserta un salto de línea y vacía el buffer hacia la pantalla. El flush tiene un coste real, así que dentro de un bucle que imprime miles de líneas, prefiere '\n': el stream se vacía por su cuenta cuando hace falta (y siempre al salir del programa).

// Bien para un mensaje puntual:
cout << "Done" << endl;

// En un bucle intensivo, prefiere esto: sin flush forzado en cada iteración:
for (int i = 0; i < 1000000; ++i)
    cout << i << '\n';

Leer con cin y >>

cin >> variable lee un token delimitado por espacios en blanco y lo convierte al tipo de la variable. Se salta cualquier espacio o salto de línea inicial y luego se detiene en el siguiente espacio en blanco.

Como >> se detiene en el espacio en blanco, es estupendo para números individuales y palabras sueltas, pero inútil para una frase completa: cin >> word con la entrada hello world lee solo hello y deja world en el buffer para la siguiente lectura.

Leer una línea completa con getline

Para capturar una línea entera —con espacios y todo— usa getline(cin, line), que lee todo hasta la tecla Enter en un std::string.

Esta es la herramienta correcta siempre que la entrada pueda contener espacios: nombres, direcciones, frases. Solo hay una trampa que te espera en el momento en que mezclas getline con >>.

La trampa del salto de línea entre cin y getline

Este es el error de E/S más común en C++. Cuando haces cin >> n, la extracción lee el número pero deja el salto de línea (la tecla Enter que pulsaste) en el buffer de entrada. El siguiente getline ve ese salto de línea sobrante de inmediato, considera la línea ya terminada y te entrega una cadena vacía, sin pausar nunca para esperar entrada.

int age;
string city;

cin >> age;            // escribes 30 y pulsas Enter; '\n' se queda en el buffer
getline(cin, city);    // lee el '\n' sobrante -> city queda "" (¡vacía!)

La solución es descartar ese salto de línea sobrante con cin.ignore después del >> y antes del getline:

cin.ignore(numeric_limits<streamsize>::max(), '\n') salta caracteres hasta que se ha comido un salto de línea (o ha llegado al final de la entrada). Es la versión robusta: la más corta cin.ignore() solo descarta un único carácter, lo que se rompe si el usuario escribió espacios adicionales tras el número. Acostúmbrate a usar la forma completa por hábito.

Cuando la entrada falla

Si el usuario escribe letras donde esperabas un número, la extracción falla: cin entra en un estado de error y la variable de destino queda sin cambios (puesta a 0 desde C++11). Peor aún, una vez que cin está en estado fallido, toda lectura posterior se omite silenciosamente también, así que puedes acabar en un bucle infinito.

La recuperación siempre tiene dos pasos: cin.clear() reinicia las banderas de error para que el stream vuelva a ser usable, y cin.ignore(...) descarta los caracteres conflictivos que siguen atascados en el buffer. Si omites el ignore, la entrada errónea se queda ahí, así que el siguiente >> vuelve a fallar: el clásico bucle infinito. Comprobar cin >> n directamente en la condición funciona porque el stream se convierte en false cuando está en estado fallido.

Errores comunes que evitar

  • Usar cin >> s para una frase. Se detiene en el primer espacio. Usa getline para cualquier cosa con espacios.
  • Olvidar cin.ignore entre >> y getline. El salto de línea sobrante te da una línea vacía. Limpia el buffer primero.
  • Recurrir a endl en todas partes. Cada uno fuerza un flush. Usa por defecto '\n' y reserva endl para cuando la salida realmente deba aparecer ya.
  • Ignorar un cin fallido. Las letras en una lectura numérica dejan cin roto; siempre haz clear() y luego ignore() antes de volver a leer.

Siguiente: Streams de cadenas

La E/S por consola y el manejo de cadenas se unen en los streams de cadenas. Un stringstream te ofrece los mismos operadores << y >>, pero apuntados a una cadena en memoria en lugar de a la consola: perfecto para parsear una línea en números, construir texto formateado y convertir entre cadenas y otros tipos sin tocar nunca el teclado.

Preguntas frecuentes

¿Por qué getline se salta la entrada justo después de usar cin en C++?

cin >> x lee el número pero deja en el buffer el salto de línea que pulsaste. El siguiente getline lee hasta ese salto de línea sobrante y devuelve una cadena vacía de inmediato. Límpialo primero con cin.ignore(numeric_limits<streamsize>::max(), '\n'); después del >> y antes del getline.

¿Cuál es la diferencia entre endl y \n en C++?

Ambos terminan la línea, pero endl además vacía (flush) el buffer de salida hacia la pantalla, mientras que '\n' solo inserta un salto de línea. El flush tiene un coste: en un bucle ajustado, prefiere '\n' y deja que el stream se vacíe por su cuenta. Usa endl solo cuando realmente necesites que la salida aparezca ahora mismo.

¿Cómo leo una línea completa de texto incluyendo espacios en C++?

Usa getline(cin, line), no cin >> line. El operador >> se detiene en el primer espacio en blanco, por lo que solo captura una palabra. getline lee todo hasta la tecla Enter en un std::string, espacios incluidos.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR