La forma correcta de leer un archivo línea a línea en C++ es while (std::getline(f, linea)). El ejemplo que había antes en esta página usaba otro bucle, muy extendido, que tiene tres errores a la vez. Lo hemos ejecutado para que se vean.
También te puede interesar
El bucle que no hay que escribir
char cadena[128];
ifstream fe("salida/notas.txt");
while (!fe.eof()) {
fe >> cadena;
cout << cadena << endl;
}El archivo tiene tres líneas: «Primera línea», «Segunda línea» y «Tercera línea». Esto es lo que imprime:
salidaPrimera línea Segunda línea Tercera línea línea
Tres errores:
| Error | Por qué |
|---|---|
| Lee palabras, no líneas | >> se detiene en cada espacio |
| La última palabra sale dos veces | eof() solo se vuelve cierto después de un intento de lectura fallido; esa vuelta de más imprime lo que quedaba en cadena |
| Puede escribir fuera de la memoria | char cadena[128]: una palabra de más de 127 caracteres se sale del arreglo |
El segundo es el más famoso. while (!eof()) pregunta «¿he llegado ya al final?», pero el flujo no lo sabe hasta que intenta leer y no puede. Así que hay una vuelta extra, la lectura falla, cadena conserva lo anterior y se imprime otra vez.
La forma correcta
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::ifstream f("salida/notas.txt");
if (!f) {
std::cerr << "no se pudo abrir salida/notas.txt\n";
return 1;
}
std::string linea;
int n = 0;
while (std::getline(f, linea)) {
std::cout << ++n << ": " << linea << "\n";
}
}salida1: Primera línea 2: Segunda línea 3: Tercera línea
std::getline lee hasta el salto de línea y devuelve el propio flujo, que se puede usar como condición: es cierto si la lectura salió bien. La lectura y la comprobación son la misma operación, así que no hay vuelta de más. Y std::string crece lo que haga falta, sin límite de 128 caracteres.
system("pause") para que la ventana de la consola de Windows no se cerrase al acabar. Ejecuta una orden del sistema solo para esperar una tecla, y en Linux o macOS no existe esa orden. Si ejecutas el programa desde una terminal abierta, no hace falta.Todo el código se compiló con GCC 16 en modo C++20, con todos los avisos activados, y se ejecutó en un contenedor limpio antes de publicar esta página; las salidas están copiadas de esa ejecución.
¿Existe alguna forma de que los espacios no delimiten la lectura de la cadena?
void leerArchivo(){
string cadena;
ifstream datos(«Estructura.txt»);
if(datos.fail()){
cout<<"Texto entrada Estructura.txt no existe"<<endl;
}else{
while(!datos.eof()){
getline(datos,cadena); //con esta funcion tomas la linea(limitada por \n)
cout<<cadena<<endl;
}
}
}
haces dos getlines seguidos, osea lees la linea 2 pero no la guardas
¿Hay algún algoritmo que me deje leer una linea en especifico ? por ejemplo que lee solo la segunda linea del archivo.