• Jueves 14 de Noviembre de 2024, 23:06

Autor Tema:  Ficheros en C++  (Leído 1147 veces)

JoniJnm

  • Nuevo Miembro
  • *
  • Mensajes: 3
  • Nacionalidad: es
    • Ver Perfil
    • http://www.jonijnm.es
Ficheros en C++
« en: Domingo 4 de Julio de 2010, 14:35 »
0
Hola,

Necesito hacer una copia manual de un archivo a otro y para ello uso:
Código: C++
  1. ifstream original;
  2. ofstream nuevo;
  3. string s; //string auxiliar
  4.  
Bueno, pues voy cogiendo datos del original y añadiéndolo al nuevo:
Código: C++
  1. original.open("original.txt");
  2. original.good(); // da true
  3. nuevo.open("nuevo.txt");
  4. nuevo.good(); // da true
  5.  
  6. while (!original.eof()) {
  7.     getline(original, s);
  8.     // Aquí compruebo cosas del string para saber si tengo que añadirlo o no (el fichero no lo toco)
  9.     // así que no puedo pasar char por char
  10.     if (condicion)
  11.         nuevo<<s;
  12. }
  13. original.fail(); // da 'true' AQUÍ ESTÁ EL PROBLEMA
  14. original.bad(); // da false
  15. nuevo.fail(); // da false
  16.  
  17. original.close();
  18. nuevo.close();
  19.  
  20. // Cuando vuelvo a abrir el original:
  21. original.open("original.txt");
  22. original.good(); // da false así que no puedo leer ni hacer nada
  23.  
  24. // Si volviese a abrir el nuevo:
  25. nuevo.open("nuevo.txt");
  26. nuevo.good(); // da true
  27.  
Como veis, cuando vuelvo a abrir el original fail() no me devuelve false. Así que falla algo, bad() no falla, es el "failbit". El problema de esto es que cuando cierro los dos ficheros, no puedo volver a abrir el original (al reabrirlo original.good() no devuelve true).

Por lo que he leído, failbit puede fallar porque justo antes del eof se coja el último caracter nulo del objeto, pero entonces qué tengo que hacer? Necesito abrirlo dos veces. No sé si tiene que ver algo que el fichero esté en UTF-8 sin/con bom o ANSI

El contenido del fichero se copia bien, el problema es, como digo, que no puedo abrir, copiar, cerrar y volver a abrir. Es como si el fichero no se cerrara bien.

Alguien sabe qué puede estar pasando? Gracias!

r0d

  • Miembro activo
  • **
  • Mensajes: 37
  • Nacionalidad: fr
    • Ver Perfil
    • http://r0d.developpez.com/index-es.php
Re: Ficheros en C++
« Respuesta #1 en: Miércoles 7 de Julio de 2010, 03:14 »
0
Hola,

primero, si el original.fail() devuelve true, no significa que haya un problema. Esto significa que alguno de los dos bits de control (failbit or badbit) esta puesto a true.
En nuestro caso, es el failbit que se pone a true cuando, el en bucle anterior, intentas hacer un getline() y que este getline() falla. Para ser preciso, es cuando el getline falla que el failbit y el eofbit se ponen a true (por eso el original.eof() devuelve true despues, y se sale del bucle).

segundo, no solemos trabajar asi con los fstreams.
En ves de lo que haces, oesa el siguiente:
Código: Text
  1. ifstream original;
  2. ofstream nuevo;
  3. string s; //string auxiliar
  4.  
  5. original.open("original.txt");
  6. bool b = original.good(); // da true
  7. nuevo.open("nuevo.txt");
  8. b = nuevo.good(); // da true
  9.  

solemos hacer asi:
Código: Text
  1. ifstream original( "original.txt" );
  2. if ( !original ) // ver nota [1]
  3.    return error;
  4.  
  5. ofstream nuevo( "nuevo.txt" );
  6. if ( !nuevo ) // ver nota [2]
  7.    return error_critical_hd;
  8.  
  9. // y ya esta: si llegamos aqui es que todo esta bien
  10.  
  11.  

tercero: la segunda parte de tu códido (todo lo que hay despues del bucle), no hace nada y/o no sirve para nada. Salvo el nuevo.good() que efectivamente te dice si todo esta bien con tu nuevo fichero, pero si algo pasa mal en el bucle tal como esta, este programa peta antes de llegar al nuevo.good() ese.

Vamos a ver.
Despues del bucle, haces un original.close(). Vale, esto cierre el aceso al fichero. Pero la variable original (de tipo ifstream) sigue en la pila (stack). Y la posicion de su cursor no ha cambiado. Asi que cuando lo vuelves a abrir, su cursor sigue estando posicionado al final, y ademas con el failbit a true. Si quieres reutilizar la misma variable para seguir manipulando el mismo fichero, tienes que reposicionar el cursor, utilizando la función seekg().

Espero que ayuda.
Saludos.

notas:
[1] la explicacion de esto es un poco complicado, porque lo que hace el compilador aqui es un cast del ifstream en void* para aplicar el operator void*( ) const; (este operador hace poco más que una llamada a la funcion fail()) de la clase ifstream, pero es la mejor manera de hacer porque entre otros es thread safe.

[2] misma historia. Esta manera de hacer tambien tiene la ventaja que esto falla solo cuando es impossible crear cualquier tipo de fichero, es decir cuando hay un problema gordo con el disco duro.

JoniJnm

  • Nuevo Miembro
  • *
  • Mensajes: 3
  • Nacionalidad: es
    • Ver Perfil
    • http://www.jonijnm.es
Re: Ficheros en C++
« Respuesta #2 en: Miércoles 7 de Julio de 2010, 16:12 »
0
Muchas gracias r0d, lo probaré, aunque al final pasé todo el fichero a un string e hice los cambios con él.

PD: Pensé en lo de que el puntero podría estar al final, pero me dije 'lo pondrá el open al principio, digo yo'. Además no sabía cómo ponerlo al principio.

Saludos y gracias!