Leer una línea entera
cin >> text lee una sola palabra: se detiene en el primer espacio. Para leer todo lo que el usuario escribió hasta la tecla Enter, espacios incluidos, usa std::getline del encabezado <string>:
#include <iostream>
#include <string>
int main() {
std::string name;
std::cout << "Full name: ";
std::getline(std::cin, name);
std::cout << "Hello, " << name << "!\n";
}
Si escribes Ada Lovelace, imprime Hello, Ada Lovelace!. Con std::cin >> name imprimiría Hello, Ada! y dejaría Lovelace esperando en la entrada.
La firma es:
std::istream& std::getline(std::istream& input, std::string& text);
std::istream& std::getline(std::istream& input, std::string& text, char delim);
inputes cualquier stream de entrada:std::cin, un archivo abierto constd::ifstreamo unstd::istringstreamconstruido a partir de una cadena.textse reemplaza (no se le añade nada al final) con los caracteres leídos.delimes el carácter que termina la lectura. Por defecto es'\n'. El delimitador se quita del stream y no se guarda entext.- El valor de retorno es el propio stream, y eso es lo que te permite comprobarlo en una condición.
Como getline funciona igual en cualquier stream de entrada, los ejemplos ejecutables de esta página leen de un std::istringstream con un texto fijo. Así la salida es predecible sin tener que escribir nada. Para leer del teclado, cambia la variable del stream por std::cin.
Salida:
[Ada Lovelace]
[Alan Turing]
Los corchetes muestran que el salto de línea no forma parte de ninguna de las dos cadenas.
getline después de cin >> devuelve una cadena vacía
Este es el problema más común con getline. Lees un número con >>, luego una línea con getline, y el getline parece saltarse:
Salida:
age: 30
city: []
input >> age lee los caracteres 30 y se detiene en el primer carácter que no puede formar parte de un número, el salto de línea. Ese salto de línea se queda en el stream. Después getline lee hasta el siguiente salto de línea, encuentra uno de inmediato y devuelve una cadena vacía. Con std::cin, el efecto es que el programa nunca se detiene a esperar la segunda respuesta.
Hay dos soluciones estándar. Las dos van entre el >> y el getline.
Solución 1: descartar el resto de la línea con ignore.
Salida:
age: 30
city: [Paris]
ignore(n, '\n') descarta caracteres hasta que ha quitado un salto de línea o n caracteres, lo que ocurra primero. Pasar el mayor std::streamsize posible significa "hasta el salto de línea, esté donde esté". También quita cualquier cosa que el usuario escribiera después del número en la misma línea, como espacios al final. Con el teclado, la línea es std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');, y necesita #include <limits>.
Un std::cin.ignore() sin argumentos descarta exactamente un carácter. Funciona cuando el salto de línea va justo después del número, y falla en cuanto hay un espacio antes.
Solución 2: saltar los espacios en blanco iniciales con std::ws.
Salida:
age: 30
city: [Paris]
std::ws es un manipulador que consume todos los espacios en blanco (espacios, tabuladores, saltos de línea) en la posición actual. input >> std::ws devuelve el stream, así que puede pasarse directamente a getline. También salta líneas en blanco y espacios iniciales, lo que resulta cómodo para nombres y ciudades, pero es incorrecto cuando los espacios iniciales o una línea vacía son una entrada con significado. En ese caso usa ignore.
Leer hasta el final de la entrada
getline devuelve el stream, y un stream se convierte en false cuando falla una lectura. Cuando no quedan más líneas, getline falla, así que un bucle while a su alrededor lee todas las líneas y se detiene al final:
Salida:
1: [apples 3]
2: [bread 1]
3: []
4: [milk 2]
read 4 lines
Dos detalles de esa salida:
- Una línea vacía sigue siendo una lectura correcta. Da una cadena vacía y el bucle continúa. Solo llegar al final de la entrada lo detiene.
- La última línea no necesita un salto de línea al final. Si el texto terminara en
milk 2sin\n,getlinela devolvería igualmente, y la siguiente llamada fallaría.
Con std::cin, el mismo bucle lee hasta que termina la entrada. Eso ocurre cuando la entrada llega redirigida desde un archivo (./program < data.txt), o cuando el usuario pulsa Ctrl+D en macOS y Linux, o Ctrl+Z y luego Enter en Windows.
Evita el patrón while (!input.eof()) { std::getline(input, line); ... }. eof() solo se vuelve verdadero después de que una lectura ya haya llegado al final, así que el cuerpo se ejecuta una vez de más con una lectura fallida y un line desactualizado. Pon la llamada a getline en la condición.
Leer un archivo línea a línea
Los archivos usan el mismo bucle. Abre el archivo con std::ifstream de <fstream>, comprueba que se abrió y lee:
Salida:
1. Ada 92
2. Grace 88
3. Alan 95
if (!file) detecta un archivo que no existe o una ruta equivocada antes del bucle. Sin esa comprobación, el bucle simplemente lee cero líneas, lo que parece un archivo vacío en lugar de un error. El archivo se cierra automáticamente cuando file sale de ámbito al final de main.
Los archivos guardados en Windows terminan cada línea con \r\n. Cuando se lee un archivo así en Linux o macOS, getline quita el \n pero conserva el \r, así que cada línea termina con un retorno de carro invisible que rompe comparaciones como line == "done". Quítalo después de leer:
if (!line.empty() && line.back() == '\r') {
line.pop_back();
}
Usar un delimitador personalizado
El tercer argumento cambia el carácter que termina cada lectura. Un uso habitual es dividir una línea por comas. Lee primero la línea y luego divídela con un std::istringstream:
Salida:
fields: 3
[Ada Lovelace]
[36]
[London]
La coma se quita del stream y no se guarda, igual que el salto de línea en la forma por defecto. Ten en cuenta que, con un delimitador personalizado, el salto de línea es un carácter normal. Si llamas a std::getline(file, field, ',') directamente sobre un archivo de varias líneas, el último campo de una línea y el primero de la siguiente llegan unidos, como en "London\nGrace Hopper". Leer una línea cada vez y dividir cada línea por separado lo evita. La página de streams de cadenas trata std::istringstream con más detalle, incluida la conversión de campos como "36" a números.
std::getline vs cin.getline
También existe una función miembro con un nombre parecido:
char buffer[20];
std::cin.getline(buffer, 20); // función miembro, array de char de tamaño fijo
std::string text;
std::getline(std::cin, text); // función libre, std::string
cin.getline escribe en un array de char y guarda como máximo size - 1 caracteres más el '\0' final. Una línea más larga deja el stream en estado fallido, y todas las lecturas posteriores se omiten hasta que llamas a std::cin.clear(). std::getline con un std::string no tiene ningún límite de longitud que gestionar. Úsalo salvo que trabajes con una API que exija un array de char.
Errores comunes
- Mezclar
>>ygetlinesin limpiar el salto de línea. Añadeignore(...)o usastd::wsentre ambos. La página de entrada y salida muestra el mismo problema constd::ciny cómo recuperarte cuando falla una lectura numérica. - Llamar a
getline(std::cin, number)con unint.getlinesolo lee en unstd::string. Lee la línea y luego conviértela constd::stoio con unstd::istringstream. - Hacer el bucle con
eof(). Comprueba la propia llamada agetline:while (std::getline(input, line)). - Olvidar
#include <string>. Elstd::getlinepara strings se declara en<string>. Algunos compiladores lo dejan pasar a través de<iostream>, y luego el código falla con otro compilador. - No comprobar que el archivo se abrió. Una ruta equivocada hace que
std::ifstreamfalle en silencio y que el bucle de lectura se ejecute cero veces.
Preguntas frecuentes
¿Qué hace getline en C++?
std::getline(stream, text) lee caracteres de stream en el std::string text hasta llegar a un salto de línea, y luego quita ese salto de línea del stream sin guardarlo. A diferencia de cin >> text, conserva los espacios, así que lee una línea entera, como un nombre completo o una frase.
¿Por qué se salta getline después de cin >> en C++?
cin >> number deja de leer en el salto de línea que escribiste después del número y deja ese salto de línea en el buffer de entrada. El siguiente getline lo encuentra de inmediato y devuelve una cadena vacía. Descártalo antes con std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');, o llama a std::getline(std::cin >> std::ws, text) para saltar los espacios en blanco iniciales.
¿Cómo uso getline con un delimitador distinto del salto de línea?
Pasa el delimitador como tercer argumento: std::getline(stream, field, ','). Lee hasta la siguiente coma, guarda el texto anterior a ella y descarta la coma. Los saltos de línea pasan a ser caracteres normales, así que esto suele combinarse con un std::stringstream construido a partir de una sola línea.
¿Cómo leo un archivo línea a línea en C++?
Ábrelo con std::ifstream file("data.txt"); y recórrelo con while (std::getline(file, line)) { ... }. getline devuelve el stream, que se convierte en false cuando no quedan más líneas, así que el bucle se detiene al final del archivo.
¿Cuál es la diferencia entre cin.getline y getline?
std::getline(std::cin, text) es una función libre que lee en un std::string, que crece para que quepa cualquier línea. std::cin.getline(buffer, size) es una función miembro que lee en un array de char de tamaño fijo y falla si la línea tiene más de size - 1 caracteres. Usa std::getline con std::string salvo que tengas un motivo para usar arrays sin más.