elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Acceso aleatorio a archivos binarios, a ver si alguien puede ayudarme
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: Acceso aleatorio a archivos binarios, a ver si alguien puede ayudarme  (Leído 8,763 veces)
Awraaaauu

Desconectado Desconectado

Mensajes: 6


Ver Perfil
Acceso aleatorio a archivos binarios, a ver si alguien puede ayudarme
« en: 23 Junio 2010, 04:41 am »

Si alguien ve que lo que digo es una tontería que me corrija y pase de leer el código.

Mi intención aquí era escribir y leer de un archivo binario usando streams. De manera que Datos -> Estructura(a lo buffer) -> archivo.dat y viceversa.

Para saber dónde y desde dónde leer he usado seekg y seekp, multiplicando el número de registro por sizeof(estructura).

El problema es que cuando introduzco un segundo registro me sobrescribe el primero con NULL las veces que sea necesario hasta llenar el hueco.

Ahí va el código:
Código
  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <fstream>
  5. using namespace std;
  6. //Estrucutra / Buffer
  7. typedef struct {
  8.       char nombre[34];
  9.       int ano;
  10.       short dia;
  11.       short mes;
  12.       } Cumple;
  13. //Prototipos      
  14. void introduccion();      
  15. char ElegirConsulta();
  16. void ConsultaID();
  17. void grabado();
  18. void lectura();
  19. //Variables Globales
  20. char meses[12][11] = {"Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"};
  21. long nRegistros = 0;
  22. long nBytes = 0;
  23. int id;
  24. Cumple pers;
  25. //Función Principal
  26. int main() {
  27.    int opt;
  28.    bool bucle = false;
  29.    while(!bucle)      {
  30.    system("cls");
  31.    ifstream fichero("datos.dat", ios::in | ios::binary);                  
  32.    fichero.seekg(0, ios::end); // Colocar el cursor al final del fichero
  33.    nBytes = fichero.tellg(); // Tamaño en bytes
  34.    nRegistros = fichero.tellg()/sizeof(Cumple); // Tamaño en registros
  35.    fichero.close();
  36.    cout << "Acci\242n:" << endl;
  37.    cout << " 1 - Introducir datos" << endl;
  38.    cout << " 2 - Consultar datos" << endl;
  39.    cout << "99 - Salir" << endl;
  40.    cout << "Opci\242n: ";
  41.    cin >> opt;
  42.    switch(opt) {
  43.               case 1:
  44.                 introduccion();
  45.                 break;
  46.               case 2:
  47.                    if(ElegirConsulta() == 'a') ConsultaID();
  48.                    break;
  49.               case 99:
  50.                    cout << "Vete ya CO\245O!!!" << endl;
  51.                    cin.get();
  52.                    cin.get();
  53.                    bucle = true;
  54.                    }
  55.                    }
  56.    return 0;
  57. }
  58. //Función de introducción de datos
  59. void introduccion() {
  60.     bool correcto = false;
  61.     char op;
  62.     cin >> id;
  63.     while(!correcto) {
  64.     system("cls");
  65.     cout << "ID: " << id << endl;
  66.     cout << "Nombre: "; cin >> pers.nombre; cout << endl;
  67.     cout << "A\244o: "; cin >> pers.ano; cout << endl;
  68.     cout << "Mes: "; cin >> pers.mes; cout << endl;
  69.     cout << "D\241a: "; cin >> pers.dia; cout << endl;
  70.     cout << endl << endl;
  71.     cout << "Datos introducidos: " << endl;
  72.     cout << pers.nombre << " naci\242 el " << pers.dia << " de " << meses[pers.mes-1] << " de " << pers.ano << endl;
  73.     cout << "Es esto correcto?(S/n)" << endl;
  74.     cin >> op;
  75.     if(op == 'S' || op == 's') correcto = true;
  76.     }
  77.     grabado();
  78.     }
  79. //Menu de consulta
  80. char ElegirConsulta() {
  81.     char op;
  82.     system("cls");
  83.     cout << "C\242mo quieres consultar?" << endl;
  84.     cout << "a) Por ID" << endl;
  85.     cout << "b) Por nombre" << endl; //Por hacer
  86.     cout << "x) Atr\240s" << endl;
  87.     cout << "Opci\242n: ";
  88.     cin >> op;
  89.     return op;
  90.     }
  91. //Función de Consulta de datos por ID
  92. void ConsultaID() {
  93.     system("cls");
  94.     cout << "Escribe ID: ";
  95.     cin >> id;
  96.     lectura();
  97.     cout << pers.nombre << " naci\242 el " << pers.dia << " de " << meses[pers.mes-1] << " de " << pers.ano << endl;
  98.     cin.get();
  99.     cin.get();
  100.     }
  101. //Función de grabado de datos en fichero binario
  102. void grabado() {
  103.     fstream grabado;
  104.     grabado.open("datos.dat", ios::out | ios::trunc | ios::binary);
  105.     grabado.seekp(id*sizeof(Cumple), ios::beg);
  106.     grabado.clear();
  107.     grabado.write((const char *)&pers, sizeof(Cumple));
  108.     grabado.close();
  109.     }
  110. //Función de lectura de datos de fichero binario
  111. void lectura() {
  112.     fstream lectura;
  113.     lectura.open("datos.dat", ios::in | ios::binary);
  114.     lectura.seekg(id*sizeof(Cumple), ios::beg);
  115.     lectura.read((char *)&pers, sizeof(Cumple));
  116.     lectura.close();
  117.     }
  118.  

¿Alguien sabe qué hago mal?

Por cierto, en WinXP, 32bits, con DevC++


« Última modificación: 23 Junio 2010, 06:35 am por Littlehorse » En línea

Littlehorse
All the world's a stage
Moderador
***
Desconectado Desconectado

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: Acceso aleatorio a archivos binarios, a ver si alguien puede ayudarme
« Respuesta #1 en: 23 Junio 2010, 06:34 am »

Bueno lo primero y principal es que deberías no utilizar tanto las variables globales. Hacen el código un poco mas difícil de seguir ya que cualquier función puede modificar su contenido.
En cuanto al problema, el principal esta en la apertura del archivo. Tanto ios::out como ios::out|ios::trunc primero descartan el contenido (crean el archivo solo si no existe, pero descartan el contenido existente en el).

Otra cosa que veo que deberías modificar es el método del calculo de posiciones, es bastante propenso a errores.
Supongamos que no tenes ningún dato, y el ID es 1400, tu archivo quedaría algo así:

1400*sizeof(data)bytes
NULL|NULL|NULL|NULL|| contenido ||


lo cual no es lo mas adecuado y de seguro te traerá problemas como archivos excesivamente grandes, punteros a archivo que no apuntan donde deben, superposición de datos y demás.

No he visto mucho mas, pero también deberías chequear los estados del stream (failbit, badbit, etc) para asegurarte de evitar otros tipos de errores.

Como ultimo, las etiquetas GeSHI utilízalas de esta forma:

C
[code=c]codigo[/code]

C++
[code=cpp]codigo[/code]

Saludos!


En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
Awraaaauu

Desconectado Desconectado

Mensajes: 6


Ver Perfil
Re: Acceso aleatorio a archivos binarios, a ver si alguien puede ayudarme
« Respuesta #2 en: 23 Junio 2010, 06:44 am »

Muchas gracias por tú respuesta.

Se que el código es una "basurita", pero realmente la única función que tenía era conseguir aprender lo de los binarios, le adorné con lo del calendario para que luego no me quedara un exe inútil.

¿Hay alguna función para lo que busco o tengo que crear un buffer para TOODOO el archivo?
En línea

Littlehorse
All the world's a stage
Moderador
***
Desconectado Desconectado

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: Acceso aleatorio a archivos binarios, a ver si alguien puede ayudarme
« Respuesta #3 en: 23 Junio 2010, 07:07 am »

No no hay ninguna. Si queres escribir los datos en forma aleatoria, basta con poner el puntero en una posición relacionada con algún criterio variante, lo cual es precisamente lo que estas haciendo ahora y teóricamente mal no esta (a pesar que tenga los problemas que ya mencione antes). El problema radica en que en cada apertura descartas el contenido del archivo existente.

Obviamente tenes mil formas de ordenar el archivo, lo ideal en este caso seria que cada estructura este detras de la otra en pos de no perder el acceso aleatorio y obtener un archivo lo mas reducido posible.

No veo la necesidad de crear un buffer para todo el archivo, no te daría ninguna ventaja respecto de lo que estas haciendo y en algún punto incluso te podría traer problemas cuando el tamaño del archivo sea considerablemente grande.

Saludos
En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
Awraaaauu

Desconectado Desconectado

Mensajes: 6


Ver Perfil
Re: Acceso aleatorio a archivos binarios, a ver si alguien puede ayudarme
« Respuesta #4 en: 23 Junio 2010, 08:26 am »

Mi pregunta es:

¿Cómo evitar que lo descarte?
En línea

Littlehorse
All the world's a stage
Moderador
***
Desconectado Desconectado

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: Acceso aleatorio a archivos binarios, a ver si alguien puede ayudarme
« Respuesta #5 en: 23 Junio 2010, 17:50 pm »

Modificando la apertura del archivo para que no vacié el contenido, busca sobre los métodos de apertura. ::app por ejemplo te podría servir, pero primero tienes que modificar el método de calculo de posiciones.

Saludos
En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
Awraaaauu

Desconectado Desconectado

Mensajes: 6


Ver Perfil
Re: Acceso aleatorio a archivos binarios, a ver si alguien puede ayudarme
« Respuesta #6 en: 24 Junio 2010, 00:02 am »

Muchas gracias, no conocía ese método. Aprendí de un manual bastante incompleto.
En línea

Littlehorse
All the world's a stage
Moderador
***
Desconectado Desconectado

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: Acceso aleatorio a archivos binarios, a ver si alguien puede ayudarme
« Respuesta #7 en: 24 Junio 2010, 00:14 am »

De nada, para eso estamos  :D. En cuanto a lo del manual, no se cual estarás leyendo pero tenes un post en las chinchetas con varios libros para elegir.

Cualquier cosa ya sabes.

Saludos!
En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
Awraaaauu

Desconectado Desconectado

Mensajes: 6


Ver Perfil
Re: Acceso aleatorio a archivos binarios, a ver si alguien puede ayudarme
« Respuesta #8 en: 24 Junio 2010, 03:15 am »

Sigue habiendo un problemilla.

::app me sitúa al final del fichero siempre antes de cualquier operación de salida, incluso después de hacer seekp

Bueno, voy a investigar un poco por mi cuenta. Si no consigo nada lo haré sin streams.

En línea

nicolas_cof


Desconectado Desconectado

Mensajes: 348


Into the Wild


Ver Perfil WWW
Re: Acceso aleatorio a archivos binarios, a ver si alguien puede ayudarme
« Respuesta #9 en: 24 Junio 2010, 15:20 pm »

Awraaaauu, prueba con ios::ate en vez de ios::app, ya que con ::app incluso si se cambia la posicion en el archivo siempre se escribe al final de este.

Salu10.
En línea

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
MediaFire impide el acceso a sus archivos desde Google en lo que puede ser la...
Noticias
wolfbcn 2 4,166 Último mensaje 4 Febrero 2012, 15:59 pm
por farresito
¿Duda que archivos puede estar el spoiler de identi alguien me dice ?
Foro Libre
Weeken 0 1,763 Último mensaje 28 Marzo 2013, 05:18 am
por Weeken
Leer archivos de acceso aleatorio con reinterpet_cast « 1 2 »
Programación C/C++
patilanz 13 6,111 Último mensaje 24 Marzo 2014, 23:13 pm
por patilanz
Duda Manejo De Archivos De Acceso Aleatorio
Programación C/C++
Omar_2013 2 2,482 Último mensaje 1 Abril 2014, 20:22 pm
por Omar_2013
router acceso aleatorio
Hacking Wireless
onic 8 4,488 Último mensaje 19 Agosto 2014, 15:21 pm
por simorg
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines