Duda con Ficheros C++

Iniciado por 98Fran, 15 Septiembre 2019, 00:27 AM

0 Miembros y 1 Visitante están viendo este tema.

98Fran

Cuando imprime el contenido del .txt por la consola, al final del programa me imprime 2 endl, por? No debería ser 1 solo endl?

Código (cpp) [Seleccionar]
#include <iostream>
#include <fstream>

void LecturaArchivo();

int main(){

LecturaArchivo();

return 0;
}

void LecturaArchivo(){
std::string Ruta, Frase;
std::ifstream Archivo;

std::cout << "Digite la ruta del archivo para abrir entre \"\"\nRuta: ";

std::getline(std::cin,Ruta);

Archivo.open(Ruta.c_str(),std::ios::in);

if (Archivo.fail()){
std::cout << "No se pudo abrir el Archivo";
exit(1);
}

std::cout << "\n\n";
while (!Archivo.eof()){
std::getline(Archivo,Frase);
std::cout << Frase << std::endl;
}
}

EdePC

Saludos,

- Lo he probado y solo me imprime un endl, no será que tu .txt ya tiene un endl extra?

K-YreX

Como bien te han dicho, si te aparecen 2 endl será que el propio fichero acaba con un endl.
Puede que el endl del final del fichero lo hayas colocado tú manualmente o que tengas alguna opción activada en el editor para que añada automáticamente un endl al final de un fichero antes de guardarlo.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

Loretz

while (!Archivo.eof()){
std::getline(Archivo,Frase);
std::cout << Frase << std::endl;
}


ese es un error muy común, un trozo de código fósil, que vaya a saber por qué se repite meticulosamente en los primeros palotes. ¿Mucho copiar y pegar el código de malos programadores del siglo XX?  (Ah, por las dudas, XX se lee "veinte")

Bueno, si te fijas un poco en lo que hace ese fragmento de código, Archivo no tiene activa la señal de eof hasta que no se pretenda leer más allá de la última linea, o ¿de qué otra manera sabría Archivo que se ha alcanzado la última?

A modo de curiosidad histórica, hace muchos, muchos años, creo que la última vez que se vio fue alrededor de 1960, los archivos se guardaban en cintas magnéticas, y cuando un archivo tenía una parte en una cinta y otra parte en otra, era necesario poner una "marca de fin de archivo" (de ahí el nombre eof - end of file). Entonces, un archivo tenía al final esa marca, normalmente 0xFFFF, que si fuera un int se leería como -1. Pero eso era así en la época en tus abuelos se conocieron, desde entonces las cosas han cambiado un poco, y algo que cambió son los filesystems, de modo que los archivos ya no llevan una "marca de fin de archivo", nunca más, desde hace muuuuucho tiempo.


98Fran

Cita de: Loretz en 15 Septiembre 2019, 04:08 AM
while (!Archivo.eof()){
std::getline(Archivo,Frase);
std::cout << Frase << std::endl;
}


ese es un error muy común, un trozo de código fósil, que vaya a saber por qué se repite meticulosamente en los primeros palotes. ¿Mucho copiar y pegar el código de malos programadores del siglo XX?  (Ah, por las dudas, XX se lee "veinte")

Bueno, si te fijas un poco en lo que hace ese fragmento de código, Archivo no tiene activa la señal de eof hasta que no se pretenda leer más allá de la última linea, o ¿de qué otra manera sabría Archivo que se ha alcanzado la última?

A modo de curiosidad histórica, hace muchos, muchos años, creo que la última vez que se vio fue alrededor de 1960, los archivos se guardaban en cintas magnéticas, y cuando un archivo tenía una parte en una cinta y otra parte en otra, era necesario poner una "marca de fin de archivo" (de ahí el nombre eof - end of file). Entonces, un archivo tenía al final esa marca, normalmente 0xFFFF, que si fuera un int se leería como -1. Pero eso era así en la época en tus abuelos se conocieron, desde entonces las cosas han cambiado un poco, y algo que cambió son los filesystems, de modo que los archivos ya no llevan una "marca de fin de archivo", nunca más, desde hace muuuuucho tiempo.


Sabes que mas de perdió de aquella época? parece ser el respeto, tu sarcasmo sobra.

Primero, estoy aprendiendo a programar y así es como me lo están enseñando. Segundo, si eres un amargado de la vida mejor postea en otro sitio, gracias ^.^

EdePC

- Jeje, a Loretz le faltó justificar algo más para que no se le mal-interprete. He estado revisando el ebook (gratuito en inglés) C++ Notes for Professionals: https://books.goalkicker.com/CPlusPlusBook/ Capítulo 12: File i/O, Sección 12.3 Reading from a file, habla otros métodos para leer ficheros, veo no usa EOF directamente.

- Luego en la Sección 12.7: Checking end of file inside a loop condition, bad
practice?, veo algo muy similar a lo que comenta Loretz, aunque no le entiendo bien XD, e hecho algunas pruebas y no noto diferencias XD.

- Por cierto, si estás iniciando en C++, te recomendaría estos ebooks gratuitos en español:
https://openlibra.com/es/book/fundamentos-de-programacion-con-el-lenguaje-de-programacion-c-ed-2017
http://arco.esi.uclm.es/~david.villa/pensar_en_C++/pensar_en_cpp-vol1.pdf
http://arco.esi.uclm.es/~david.villa/pensar_en_C++/pensar_en_cpp-vol2.pdf

-- Ya luego revisas ebooks avanzados de tips como el de Notes for Professionals o las Referencias Oficiales.

Loretz

Cita de: 98Fran en 15 Septiembre 2019, 22:34 PM
Sabes que mas de perdió de aquella época? parece ser el respeto, tu sarcasmo sobra.

Primero, estoy aprendiendo a programar y así es como me lo están enseñando. Segundo, si eres un amargado de la vida mejor postea en otro sitio, gracias ^.^

Mis disculpas, pero la cosa no era contigo que eres la víctima. Sucede que por alguna razón hay una manía de enseñar C++ como si se estuviera en los 70s, con construcciones y rutinas propias de los 50. Y no sé muy bien por qué, pero me disgusta de sobremanera. Yo también he tenido que pasar por el mismo tratamiento de quienes enseñar vicios y usan el poder de una cátedra para que todo el mundo esté obligado a reproducirlos. Me parece francamente despreciable, y no conseguí decirlo bien.

Va una aclaración por si sirviera:

La construcción
while (!Archivo.eof()){
es por lo menos incompleta, ya la suspensión de la lectura con getline puede deberse a más de una causa.

std::ifstream tiene un operator bool, que equivale a !fail(), que es lo que permite la lectura en ciclos.
Documentación: https://en.cppreference.com/w/cpp/io/basic_ios/operator_bool

La forma canónica sería:

Código (cpp) [Seleccionar]
    while (std::getline(Archivo, Frase)) {
        std::cout << Frase << std::endl;
    }

    // Si interesa saber que ha resultado:
    // (puedes consultar la documentaciOn:
    // https://en.cppreference.com/w/cpp/io/ios_base/iostate

    if (Archivo.good())
        std::cout << "Sin error.\n";
    else if (Archivo.eof())
        std::cout << "End of file.\n";
    else if (Archivo.fail())
        std::cout << "Error de lectura.\n";
    else if (Archivo.bad())
        std::cout << "Error irrecuperable.\n";



98Fran

Cita de: EdePC en 15 Septiembre 2019, 23:47 PM
- Jeje, a Loretz le faltó justificar algo más para que no se le mal-interprete. He estado revisando el ebook (gratuito en inglés) C++ Notes for Professionals: https://books.goalkicker.com/CPlusPlusBook/ Capítulo 12: File i/O, Sección 12.3 Reading from a file, habla otros métodos para leer ficheros, veo no usa EOF directamente.

- Luego en la Sección 12.7: Checking end of file inside a loop condition, bad
practice?, veo algo muy similar a lo que comenta Loretz, aunque no le entiendo bien XD, e hecho algunas pruebas y no noto diferencias XD.

- Por cierto, si estás iniciando en C++, te recomendaría estos ebooks gratuitos en español:
https://openlibra.com/es/book/fundamentos-de-programacion-con-el-lenguaje-de-programacion-c-ed-2017
http://arco.esi.uclm.es/~david.villa/pensar_en_C++/pensar_en_cpp-vol1.pdf
http://arco.esi.uclm.es/~david.villa/pensar_en_C++/pensar_en_cpp-vol2.pdf

-- Ya luego revisas ebooks avanzados de tips como el de Notes for Professionals o las Referencias Oficiales.

Gracias!, Les echare un vistazo ^.^

98Fran

#8
Cita de: Loretz en 16 Septiembre 2019, 05:04 AM
Mis disculpas, pero la cosa no era contigo que eres la víctima. Sucede que por alguna razón hay una manía de enseñar C++ como si se estuviera en los 70s, con construcciones y rutinas propias de los 50. Y no sé muy bien por qué, pero me disgusta de sobremanera. Yo también he tenido que pasar por el mismo tratamiento de quienes enseñar vicios y usan el poder de una cátedra para que todo el mundo esté obligado a reproducirlos. Me parece francamente despreciable, y no conseguí decirlo bien.

Va una aclaración por si sirviera:

La construcción
while (!Archivo.eof()){


es por lo menos incompleta, ya la suspensión de la lectura con getline puede deberse a más de una causa.

std::ifstream tiene un operator bool, que equivale a !fail(), que es lo que permite la lectura en ciclos.
Documentación: https://en.cppreference.com/w/cpp/io/basic_ios/operator_bool

La forma canónica sería:

Código (cpp) [Seleccionar]
   while (std::getline(Archivo, Frase)) {
       std::cout << Frase << std::endl;
   }

   // Si interesa saber que ha resultado:
   // (puedes consultar la documentaciOn:
   // https://en.cppreference.com/w/cpp/io/ios_base/iostate

   if (Archivo.good())
       std::cout << "Sin error.\n";
   else if (Archivo.eof())
       std::cout << "End of file.\n";
   else if (Archivo.fail())
       std::cout << "Error de lectura.\n";
   else if (Archivo.bad())
       std::cout << "Error irrecuperable.\n";



Lo siento yo tambien, por que mi contestación está demas y fuera fe tono :( , solo busco aprender cosas nuevas y soy de las personas que le cuesta mucho entender e interiorizar todo lo nuevo si no tengo con que referenciarlo. Le echare un vistazo aun que cuando es código suelto y lo ponen con nombres complicados como: std::basic_ios<CharT,Traits> ya no se ni como escribirlo en mi código xD, al menos hay ejemplos para que me figure mas o menos como va.

LoneCoder

#9
estoy seguro que Dennis Ritchie si aun estuviera vivo con 80 años que tendria te pegaria 100.000 vueltas como programador de C/C++...a ti Loretz, a mi y a cualquiera

en cuanto a las marcas de fin de archivo, puedes utilizar EOF perfectamente ya que funciona .... pero te recomendaria que estudiases un poco mejor el sistema de lectura de ficheros con fopen() fclose() fseek() fread() y fwrite() etc ya que tu forma de acceder al fichero es un poco "ambigua"

y otra cosa, ponerse a programar en C++ sin conocer a fondo primero el C es una mala practica