Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] Problema con tellg() - Archivos

Estas en el tema de Problema con tellg() - Archivos en el foro de C/C++ en Foros del Web. Hola, como estan? aqui yo molestando con un nuevo problema jaja, a ver si me pueden ayudar. Bueno, resulta que quiero sacar el tamaño del ...
  #1 (permalink)  
Antiguo 12/08/2014, 15:13
 
Fecha de Ingreso: octubre-2011
Mensajes: 17
Antigüedad: 12 años, 6 meses
Puntos: 0
Exclamación Problema con tellg() - Archivos

Hola, como estan? aqui yo molestando con un nuevo problema jaja, a ver si me pueden ayudar. Bueno, resulta que quiero sacar el tamaño del archivo con tellg y siempre me da -1 (con tellp me da lo mismo), y no le encuentro la vuelta, no se en que puedo estar fallando.
Aca les dejo dejo el codigo

Código C++:
Ver original
  1. #include <iostream>
  2. #include <fstream>
  3.  
  4. using namespace std;
  5. class prueba {
  6.     int p;
  7. public:
  8.     void escribir();
  9.     void leer();
  10. };
  11.  
  12. void prueba::escribir() {
  13.     cin>>p;
  14. }
  15. void prueba::leer() {
  16.     cout<<"Numero "<<p<<endl;
  17. }
  18.  
  19.  
  20. int main(int argc, char *argv[]) {
  21.     prueba P[3];
  22.     fstream archivo;
  23.    
  24.     archivo.open("probar", ios::in | ios::out | ios::binary);
  25.     archivo.seekg(0);
  26.    
  27.     for(int i=0; i<3;i++){
  28.     cout<<"Numero "<<i+1<<": ";
  29.     P[i].escribir();
  30.     archivo.write((char *) &P, sizeof P);
  31.     }
  32.     archivo.seekg(0);
  33.     cout<<"\n";
  34.    
  35.     for(int i=0; i<3; i++) {
  36.     archivo.read((char *) &P, sizeof P);
  37.     P[i].leer();
  38.     }
  39.    
  40.     int L = sizeof(P);
  41.    
  42.     cout<<"\n";
  43.    
  44.     cout<<"Longitud archivo: "<<L;
  45.     cout<<"\n";
  46.    
  47.     int m;
  48.     cout<<"Ingresar numero de objeto: ";
  49.     cin>>m;
  50.     int pos = (m-1) * L;
  51.    
  52.     //cout.setf(ios::hex, ios::basefield);
  53.     cout<<"Posicion Objeto: "<<pos<<"\n";
  54.    
  55.    
  56.     archivo.seekg(0);
  57.    
  58.     int start = archivo.tellg ();
  59.     cout<<"Start: "<<start<<endl;
  60.     archivo.seekg (0, ios :: end);
  61.    
  62.     int end = archivo.tellg ();
  63.     cout<<"End: "<<end<<endl;
  64.     int size = (end - start);
  65.     cout<<"Size: "<<size<<endl;
  66.    
  67.    
  68.    
  69.     archivo.seekg(0, ios::end);
  70.     long TamTotal = archivo.tellg();
  71.     cout<<"Tamanio Total: "<<TamTotal;
  72.     cout<<"\n";
  73.     int CantObj = TamTotal/L;
  74.     cout<<"Cantidad de Objetos: "<<CantObj;
  75.    
  76.     archivo.close();
  77.    
  78.     return 0;
  79. }

Por ahi tambien puede ser que algunas de las sentencias tengan un error logico y no me estoy dando cuenta, lo raro es que siempre me da como resultado -1
  #2 (permalink)  
Antiguo 16/08/2014, 09:43
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Problema con tellg() - Archivos

Hola:
A ver si alguien te puede dar una explicación más técnica de como se comportan los objetos fstream.
Mientras, lo único que te puedo decir es que seekp() y tellp() son métodos de ostream.
Así que te puede funcionar esto. Es crear un objeto ifstream para la creación y llenado del archivo, y un objeto ofstream para su lectura:

Código C++:
Ver original
  1. int main(int argc, char *argv[])
  2. {
  3.     prueba P[3];
  4.     ofstream archivo ("probar", ios::out | ios::binary);
  5.  
  6.     for(int i=0; i<3; i++)
  7.         {
  8.             cout<<"Numero "<<i+1<<": ";
  9.             P[i].escribir();
  10.             archivo.write((char *) &P, sizeof P);
  11.         }
  12.     archivo.close();
  13.  
  14.     ifstream archivo2 ("probar", ios::in | ios::binary);
  15.  
  16.     for(int i=0; i<3; i++)
  17.         {
  18.             archivo2.read((char *) &P, sizeof P);
  19.             P[i].leer();
  20.         }
  21.  
  22.     int L = sizeof(P);
  23.  
  24.     cout<<"\n";
  25.  
  26.     cout<<"Longitud archivo: "<<L;
  27.     cout<<"\n";
  28.  
  29.     int m;
  30.     cout<<"Ingresar numero de objeto: ";
  31.     cin>>m;
  32.     int pos = (m-1) * L;
  33.  
  34.     //cout.setf(ios::hex, ios::basefield);
  35.     cout<<"Posicion Objeto: "<<pos<<"\n";
  36.  
  37.  
  38.     archivo2.seekg(0);
  39.  
  40.     int start = archivo2.tellg ();
  41.     cout<<"Start: "<<start<<endl;
  42.     archivo2.seekg (0, ios :: end);
  43.  
  44.     int end = archivo2.tellg ();
  45.     cout<<"End: "<<end<<endl;
  46.     int size = (end - start);
  47.     cout<<"Size: "<<size<<endl;
  48.  
  49.  
  50.  
  51.     archivo2.seekg(0, ios::end);
  52.     long TamTotal = archivo2.tellg();
  53.     cout<<"Tamanio Total: "<<TamTotal;
  54.     cout<<"\n";
  55.     int CantObj = TamTotal/L;
  56.     cout<<"Cantidad de Objetos: "<<CantObj;
  57.  
  58.     archivo2.close();
  59.  
  60.     return 0;
  61. }

Siento no ser de más ayuda. Bueno, también decir que hay que acostumbrase a los casting de C++. En este caso, donde pones:
Código C++:
Ver original
  1. archivo.write((char *) &P, sizeof P);
Código C++:
Ver original
  1. archivo2.read((char *) &P, sizeof P);
habría que hacer:
Código C++:
Ver original
  1. archivo2.write(reinterpret_cast<char *>(&P), sizeof(P));
Código C++:
Ver original
  1. archivo2.read(reinterpret_cast<char *>(&P), sizeof(P));

Última edición por dehm; 16/08/2014 a las 10:02
  #3 (permalink)  
Antiguo 18/08/2014, 22:22
 
Fecha de Ingreso: octubre-2011
Mensajes: 17
Antigüedad: 12 años, 6 meses
Puntos: 0
Respuesta: Problema con tellg() - Archivos

Cita:
Iniciado por dehm Ver Mensaje
Hola:
A ver si alguien te puede dar una explicación más técnica de como se comportan los objetos fstream.
Mientras, lo único que te puedo decir es que seekp() y tellp() son métodos de ostream.
Así que te puede funcionar esto. Es crear un objeto ifstream para la creación y llenado del archivo, y un objeto ofstream para su lectura:

Código C++:
Ver original
  1. int main(int argc, char *argv[])
  2. {
  3.     prueba P[3];
  4.     ofstream archivo ("probar", ios::out | ios::binary);
  5.  
  6.     for(int i=0; i<3; i++)
  7.         {
  8.             cout<<"Numero "<<i+1<<": ";
  9.             P[i].escribir();
  10.             archivo.write((char *) &P, sizeof P);
  11.         }
  12.     archivo.close();
  13.  
  14.     ifstream archivo2 ("probar", ios::in | ios::binary);
  15.  
  16.     for(int i=0; i<3; i++)
  17.         {
  18.             archivo2.read((char *) &P, sizeof P);
  19.             P[i].leer();
  20.         }
  21.  
  22.     int L = sizeof(P);
  23.  
  24.     cout<<"\n";
  25.  
  26.     cout<<"Longitud archivo: "<<L;
  27.     cout<<"\n";
  28.  
  29.     int m;
  30.     cout<<"Ingresar numero de objeto: ";
  31.     cin>>m;
  32.     int pos = (m-1) * L;
  33.  
  34.     //cout.setf(ios::hex, ios::basefield);
  35.     cout<<"Posicion Objeto: "<<pos<<"\n";
  36.  
  37.  
  38.     archivo2.seekg(0);
  39.  
  40.     int start = archivo2.tellg ();
  41.     cout<<"Start: "<<start<<endl;
  42.     archivo2.seekg (0, ios :: end);
  43.  
  44.     int end = archivo2.tellg ();
  45.     cout<<"End: "<<end<<endl;
  46.     int size = (end - start);
  47.     cout<<"Size: "<<size<<endl;
  48.  
  49.  
  50.  
  51.     archivo2.seekg(0, ios::end);
  52.     long TamTotal = archivo2.tellg();
  53.     cout<<"Tamanio Total: "<<TamTotal;
  54.     cout<<"\n";
  55.     int CantObj = TamTotal/L;
  56.     cout<<"Cantidad de Objetos: "<<CantObj;
  57.  
  58.     archivo2.close();
  59.  
  60.     return 0;
  61. }

Siento no ser de más ayuda. Bueno, también decir que hay que acostumbrase a los casting de C++. En este caso, donde pones:
Código C++:
Ver original
  1. archivo.write((char *) &P, sizeof P);
Código C++:
Ver original
  1. archivo2.read((char *) &P, sizeof P);
habría que hacer:
Código C++:
Ver original
  1. archivo2.write(reinterpret_cast<char *>(&P), sizeof(P));
Código C++:
Ver original
  1. archivo2.read(reinterpret_cast<char *>(&P), sizeof(P));
Hola, Dehm..pense que ya nadie responderia a esta problema que me surgio jaja. Gracias por contestar y por tu ayuda, mañana pruebo con esto que me decis y si me da los resultados deseados o no lo hare saber. Un abrazo
  #4 (permalink)  
Antiguo 19/08/2014, 17:13
 
Fecha de Ingreso: octubre-2011
Mensajes: 17
Antigüedad: 12 años, 6 meses
Puntos: 0
Respuesta: Problema con tellg() - Archivos

Bueno, ahora si me funciono, gracias. Lo que no entiendo bien es porque si tengo un arreglo de, por ej en este caso, tres enteros (4 bytes) el tamaño no deberia darme de 12 bytes en vez de 36? que es el valor que me da el metodo tellg().
  #5 (permalink)  
Antiguo 20/08/2014, 01:17
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Problema con tellg() - Archivos

Hola de nuevo:

Bueno, es la segunda vez que edito el post, ya que no atinaba con la respuesta correcta.
Aprovecho para corregir también la primera respuesta, ya que intuía que no era correcta.
Bueno, el caso es que creo que el motivo por el que no funcionaba seekg()/tellg() era porque no estaba bien el metodo de escritura, y se activaba el flag de error.
Prueba con estas líneas en tu código:
Código C++:
Ver original
  1. if (archivo.fail())
  2.     {
  3.         cout<<"Limpiar flags"<<endl;
  4.     }
  5.     archivo.clear();

Si hay error, te mostrará el mensaje y se limpiará el flag de error.

Sobre la duda, el problema es que al hacer la escritura, reservas el tamaño de P (12 bytes) y al hacerlo dentro del bucle, reservas un total de 3*12 bytes, que son los 36 bytes.
Creo que éste código corrige los errores, y de paso hace uso de un archivo para lectura/escritura, que es lo que querías y que yo equivocadamente te indiqué que no era posible:
Código C++:
Ver original
  1. #include <iostream>
  2. #include <fstream>
  3.  
  4. using namespace std;
  5. class prueba
  6. {
  7.     int p;
  8. public:
  9.     void escribir();
  10.     void leer();
  11. };
  12.  
  13. void prueba::escribir()
  14. {
  15.     cin>>p;
  16. }
  17. void prueba::leer()
  18. {
  19.     cout<<"Numero: "<<p<<endl;
  20. }
  21.  
  22.  
  23. int main(int argc, char *argv[])
  24. {
  25.     prueba P[3];
  26.     prueba P2[3];
  27.    
  28.     fstream archivo ("probar", ios::in | ios::out | ios::trunc | ios::binary);
  29.  
  30.     for(int i=0; i<3; i++)
  31.         {
  32.             cout<<"Numero "<<i+1<<": ";
  33.             P[i].escribir();
  34.             archivo.write(reinterpret_cast<char *>(&P[i]), sizeof(prueba));
  35.         }
  36.     archivo.seekg(0);
  37.     archivo.read(reinterpret_cast<char *>(&P2), sizeof(prueba)*3); //archivo.read(reinterpret_cast<char *>(&P2), sizeof(P));
  38.     for(int i=0; i<3; i++)
  39.         {
  40.             P2[i].leer();
  41.         }
  42.  
  43.     int L = sizeof(P);
  44.  
  45.     cout<<"\n";
  46.  
  47.     cout<<"Longitud archivo: "<<L;
  48.     cout<<"\n";
  49.  
  50.     int m;
  51.     cout<<"Ingresar numero de objeto: ";
  52.     cin>>m;
  53.     int pos = (m-1) * sizeof(P[0]);
  54.  
  55.     //cout.setf(ios::hex, ios::basefield);
  56.     cout<<"Posicion Objeto: "<<pos<<"\n";
  57.     if (archivo.fail())
  58.     {
  59.         cout<<"Limpiar flags"<<endl;
  60.     }
  61.     archivo.clear();
  62.  
  63.     archivo.seekg(0L, ios::beg);
  64.     int start = archivo.tellg ();
  65.     cout<<"Start: "<<start<<endl;
  66.  
  67.     archivo.seekg (0L, ios :: end);
  68.     int end = archivo.tellg ();
  69.     cout<<"End: "<<end<<endl;
  70.     int size = (end - start);
  71.     cout<<"Size: "<<size<<endl;
  72.  
  73.     archivo.seekg(0, ios::end);
  74.     long TamTotal = archivo.tellg();
  75.     cout<<"Tamanio Total: "<<TamTotal;
  76.     cout<<"\n";
  77.     int CantObj = TamTotal/L;
  78.     cout<<"Cantidad de Objetos: "<<CantObj;
  79.  
  80.     archivo.close();
  81.  
  82.     return 0;
  83. }

Última edición por dehm; 20/08/2014 a las 02:26 Razón: Primera respuesta incorrecta
  #6 (permalink)  
Antiguo 23/10/2014, 17:25
 
Fecha de Ingreso: octubre-2011
Mensajes: 17
Antigüedad: 12 años, 6 meses
Puntos: 0
Respuesta: Problema con tellg() - Archivos

Cita:
Iniciado por dehm Ver Mensaje
Hola de nuevo:

Bueno, es la segunda vez que edito el post, ya que no atinaba con la respuesta correcta.
Aprovecho para corregir también la primera respuesta, ya que intuía que no era correcta.
Bueno, el caso es que creo que el motivo por el que no funcionaba seekg()/tellg() era porque no estaba bien el metodo de escritura, y se activaba el flag de error.
Prueba con estas líneas en tu código:
Código C++:
Ver original
  1. if (archivo.fail())
  2.     {
  3.         cout<<"Limpiar flags"<<endl;
  4.     }
  5.     archivo.clear();

Si hay error, te mostrará el mensaje y se limpiará el flag de error.

Sobre la duda, el problema es que al hacer la escritura, reservas el tamaño de P (12 bytes) y al hacerlo dentro del bucle, reservas un total de 3*12 bytes, que son los 36 bytes.
Creo que éste código corrige los errores, y de paso hace uso de un archivo para lectura/escritura, que es lo que querías y que yo equivocadamente te indiqué que no era posible:
Código C++:
Ver original
  1. #include <iostream>
  2. #include <fstream>
  3.  
  4. using namespace std;
  5. class prueba
  6. {
  7.     int p;
  8. public:
  9.     void escribir();
  10.     void leer();
  11. };
  12.  
  13. void prueba::escribir()
  14. {
  15.     cin>>p;
  16. }
  17. void prueba::leer()
  18. {
  19.     cout<<"Numero: "<<p<<endl;
  20. }
  21.  
  22.  
  23. int main(int argc, char *argv[])
  24. {
  25.     prueba P[3];
  26.     prueba P2[3];
  27.    
  28.     fstream archivo ("probar", ios::in | ios::out | ios::trunc | ios::binary);
  29.  
  30.     for(int i=0; i<3; i++)
  31.         {
  32.             cout<<"Numero "<<i+1<<": ";
  33.             P[i].escribir();
  34.             archivo.write(reinterpret_cast<char *>(&P[i]), sizeof(prueba));
  35.         }
  36.     archivo.seekg(0);
  37.     archivo.read(reinterpret_cast<char *>(&P2), sizeof(prueba)*3); //archivo.read(reinterpret_cast<char *>(&P2), sizeof(P));
  38.     for(int i=0; i<3; i++)
  39.         {
  40.             P2[i].leer();
  41.         }
  42.  
  43.     int L = sizeof(P);
  44.  
  45.     cout<<"\n";
  46.  
  47.     cout<<"Longitud archivo: "<<L;
  48.     cout<<"\n";
  49.  
  50.     int m;
  51.     cout<<"Ingresar numero de objeto: ";
  52.     cin>>m;
  53.     int pos = (m-1) * sizeof(P[0]);
  54.  
  55.     //cout.setf(ios::hex, ios::basefield);
  56.     cout<<"Posicion Objeto: "<<pos<<"\n";
  57.     if (archivo.fail())
  58.     {
  59.         cout<<"Limpiar flags"<<endl;
  60.     }
  61.     archivo.clear();
  62.  
  63.     archivo.seekg(0L, ios::beg);
  64.     int start = archivo.tellg ();
  65.     cout<<"Start: "<<start<<endl;
  66.  
  67.     archivo.seekg (0L, ios :: end);
  68.     int end = archivo.tellg ();
  69.     cout<<"End: "<<end<<endl;
  70.     int size = (end - start);
  71.     cout<<"Size: "<<size<<endl;
  72.  
  73.     archivo.seekg(0, ios::end);
  74.     long TamTotal = archivo.tellg();
  75.     cout<<"Tamanio Total: "<<TamTotal;
  76.     cout<<"\n";
  77.     int CantObj = TamTotal/L;
  78.     cout<<"Cantidad de Objetos: "<<CantObj;
  79.  
  80.     archivo.close();
  81.  
  82.     return 0;
  83. }
Hola, dehm, primero que nada perdon que no haya respondido antes pero gracias por responder y darme la solucion correcta. Lo unico que me quede pensando es en porque declaraste dos arreglos,
yo probe el codigo con un solo arreglo y metiendo archivo.read(reinterpret_cast<char *>(&P[i]), sizeof(prueba)*3); de esta forma dentro del bucle for adonde se encuentra .leer() y me funciono igual,
lo que no se es si lo que hice es lo correcto pero en si mi pregunta es porque dos arreglos y no uno.
Por lo demas ninguna duda y por cierto si no se puede volver a responder a un post despues de un tiempo(me ausente un par de meses) pido disculpas y haganmelo saber. Saludos
  #7 (permalink)  
Antiguo 24/10/2014, 05:05
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Problema con tellg() - Archivos

Hola:

No es necesario declarar un arreglo aparte para volcar los datos.
Lo que pasa es que si usas el mismo arreglo para introducir datos, volcarlos al fichero y después recuperarlos del fichero, puede ocurrir que no sepamos si los datos que lees después de esas operaciones son los originales o realmente se ha producido una transferencia efectiva de información.
Volcando los datos del fichero a un arreglo diferente tienes la seguridad de que los datos que estas leyendo en P2 son los del fichero y no los que estaban originalmente.

Pero ese es el único motivo, no hay ninguna obligación ni tema técnico.
Saludos!

Etiquetas: int
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 22:55.