Lectura y escritura de ficheros

Started by lou, November 24, 2009, 10:02:46 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

lou

Saludos!
Bien, mi duda es la siguiente:
¿Como he de guardar, y mas tarde leer, una matriz de estructuras en un fichero?

Este es el código que tengo ahora

GLOBAL
        tp_celda tablero[SIZE_X_TAB][SIZE_Y_TAB]; //matriz de estructuras tp_celda
END

//lo que yo hago actualmente, y no funciona jeje
IF(key(_CONTROL) AND key(_S))
WHILE(key(_CONTROL) AND key(_S)) FRAME; END //controlamos que guarde una sola vez
id_file = fopen("files/"+nombre_file,O_WRITE); //abrimos el fichero
fwrite(id_file,tablero[SIZE_X_TAB][SIZE_Y_TAB]); //escribimos la matriz de estructuras
fclose(id_file); //cerramos fichero
END

IF(key(_CONTROL) AND key(_A))
WHILE(key(_CONTROL) AND key(_A)) FRAME; END //cpntrolamos que abra una sola vez
id_file = fopen("files/"+nombre_file,O_READ); //abrimos el fichero
fread(id_file,tablero[SIZE_X_TAB][SIZE_Y_TAB]); //leemos y guardamos en la matriz de estructuras
fclose(id_file);//cerramos el fichero
END


He estado leyendo los manuales que tengo, y pone que guarda secuencialmente y tal, pero no me aclaro como he de programar la lectura y escritura, porque no entiendo exactamente como lo guarda :(

A ver si alguien puede aclararme un poco las ideas! :D

Un saludo y gracias!

osk

En mi manualillo hay varios ejemplos, apartado "Trabajar con ficheros". En la wiki también.

lou

Ok. Ahora miro a ver si lo encuentro y le echo un vistazo!
Gracias!

lou

Bueno, la solución era bastante demasiado facil ><

En vez de

fwrite(id_file,tablero[SIZE_X_TAB][SIZE_Y_TAB]);
fread(id_file,tablero[SIZE_X_TAB][SIZE_Y_TAB]);

bastaba con poner

fwrite(id_file,tablero);
fread(id_file,tablero);


Gracias por el manual Osk! Hasta ahora usaba una versión antigua de ese mismo.

Windgate

Oh el manual de Osk, todavía vuelvo de vez en cuando a las versiones de Fénix después de tantos años de costumbre ;D

Me ha sorprendido la facilidad de la solución, así que se puede guardar una matriz completa pasando como parámetro sólamente el nombre de la matriz... :o

Viva Bennu, para guardar/cargar partida en mi juego de droides podría servir... Vaya vaya...
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

SplinterGU

se guardan variables sean como sean...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Windgate

En algunos lenguajes el nombre de la matriz/vector no es más que un puntero a su dirección inicial en memoria, por eso pensaba en un principio que algo así guardaría simplemente el valor de la dirección de memoria en el fichero... Curioso xD

También debo añadir que en Bennu no he usado mucho ficheros...
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Drumpi

El sistema de escritura en ficheros es muy potente, tanto que me sorprendió en su día:
Bennu reconoce el tamaño de la variable que le pases por parámetro, ya sea un tipo base, un vector/array, una estructura, un tipo definido... y no he probado con estructuras más complejas.
No se si siguen los "problemas" que había con strings por su naturaleza tan "especial", pero para eso tenemos fgets y fputs, que leen (y descartan) fin de linea y retorno de carro, independientemente de la plataforma (punto para Splinter... aunque me ha provocado alguna incompatibilidad de código ;D).
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

SplinterGU

cuidado con guardar punteros, ya que por lo general representan datos cargados en memoria que no van a corresponder a otra instancia.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Windgate

Sí, desde luego nunca guardaría el valor de puntero, en cualquier caso a lo que apunta :S
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

lou

Revivo este tema para no abrir otro, ya que trata sobre lo mismo: archivos.

Esta mañana me disponía alegremente a empezar con el guardado/carga de partidas para mi juego, cuando me he dado con un muro... invisible a primera vista, por lo menos para mi^^

Guardo el valor de varias variables en un mismo fichero, en modo O_WRITE y usando fwrite, y al cargar la partida leo en modo O_READ usado fread. He comprobado que guardo los datos en el mismo orden que los cargo. Una vez cargado, uso fclose() para cerrarlo.

Si creo una partida nueva, trasteo todo lo que quiero y guarda sin problemas, no se queja por ningun lado. Despues, cargo esa partida, y todo carga perfecto.
Aqui viene el problema... una vez cargada la partida, si modifico algun dato de uno de los arrays, peta al volver a guardar la partida, en el momento de grabar ese array :S

No entiendo porque de primeras se guarda sin problemas, pero al cargar el archivo y volver a guardar, el programa peta :(

Cabe mencionar que el array es de un tipo de dato bastante gordo (4 estructuras), que no se si tendrá algo que ver con el problema.

Si a alguien le ha pasado algo parecido, o tiene idea de porque puede ocurrir esto, porfavor ilumineme!

Gracias!

Windgate

¿Usas el mismo fichero que has cargado para guardar luego la partida? Si ya lo tenías abierto es posible que el cursor permanezca al final del mismo o algo así... Realmente no he hecho más que alguna prueba trivial con guardar/cargar partida y otras pruebas que he hecho con ficheros han sido sólo con lectura (Los editaba a mano con el notepad).

PD: Pero veo que has usado fclose, no debería haber problema en que leas y después del fclose escribas... En teoría al menos xD

También podrías borrar el fichero antes de guardarlo o algo así, a ver si soluciona el problema. Pero la verdad, es raro lo que te pasa, a ver si alguien puede aclarar algo más al respecto :P
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Drumpi

A ver si lo he entendido bien:

Primero usas FWRITE para crear un fichero y guardar los datos, luego cierras. Luego lo has abierto, lo has leido con FREAD y lo has vuelto a cerrar, tras lo que has comprobado los datos y todo está correcto.
Y por último has modificado una variable, has vuelto a abrir el fichero y al usar FWRITE te ha petado ¿no?

Es raro: si usas el modo O_WRITE, el contenido del fichero se borra entero, y el puntero de escritura se pone al principio, por lo que no deberías tener problemas. ¿Es posible que tengas algún conflicto con los permisos de usuario? A veces windows es muy puñetero según donde se escriba.

Lo cierto es que sin ver el código no se me ocurre qué puede estar ocasionando esto. Intenta reproducir el fallo usando estructuras más simples (un array de bytes, por ejemplo). Si va bien, podrías comprobar el fichero con un editor hexadecimal (en más de una ocasión me han salvado de tirarme por la ventana :D).

Tambien podrías probar con SAVE y LOAD. Para lo que haces te viene bien. personalmente prefiero usar FREAD/FWRITE con tipos de datos más sencillos (BYTE, WORD e INT, exclusivamente, leyendo cada campo de los registros uno a uno).
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

Windgate

save ( ) y load ( ) sólo permiten una variable, por grande que sea, en cada fichero, puede servir como "apaño", pero donde esté un fwrite ( ) fread ( )...

También recomiendo usar say ( ) para ver por consola los valores del identificador de fichero y alguna cosilla más de interés, no vaya a ser que estás currando con un identificador no válido porque escribiste mal el nombre o cualquiera de esos fallos que nos hacen sufrir tanto y al final son simple burrería nuestra :D
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

lou

Quote from: Drumpi on January 19, 2010, 01:55:07 AM
A ver si lo he entendido bien:

Primero usas FWRITE para crear un fichero y guardar los datos, luego cierras. Luego lo has abierto, lo has leido con FREAD y lo has vuelto a cerrar, tras lo que has comprobado los datos y todo está correcto.
Y por último has modificado una variable, has vuelto a abrir el fichero y al usar FWRITE te ha petado ¿no?
Exactamente eso, el problema viene con que solo peta con un tipo de dato. Guardo tambien tres int y otro array de estructuras más simples, que guardan sin problemas.

Quote from: Drumpi on January 19, 2010, 01:55:07 AM
Es raro: si usas el modo O_WRITE, el contenido del fichero se borra entero, y el puntero de escritura se pone al principio, por lo que no deberías tener problemas. ¿Es posible que tengas algún conflicto con los permisos de usuario? A veces windows es muy puñetero según donde se escriba.
He mirado los permisos de la carpeta y tengo permisos de lectura y escritura. :(

Quote from: Drumpi on January 19, 2010, 01:55:07 AM
Lo cierto es que sin ver el código no se me ocurre qué puede estar ocasionando esto. Intenta reproducir el fallo usando estructuras más simples (un array de bytes, por ejemplo). Si va bien, podrías comprobar el fichero con un editor hexadecimal (en más de una ocasión me han salvado de tirarme por la ventana :D).
No tengo ni idea de hexadecimal, no sabria que buscar jajajaja

Quote from: Drumpi on January 19, 2010, 01:55:07 AM
Tambien podrías probar con SAVE y LOAD. Para lo que haces te viene bien. personalmente prefiero usar FREAD/FWRITE con tipos de datos más sencillos (BYTE, WORD e INT, exclusivamente, leyendo cada campo de los registros uno a uno).
A una mala puedo probar a guardar la variable que me da problemas así, y el resto con fread y fwrite. Ya buscare como funcionan SAVE y LOAD que nunca las he usado.

Quote from: Windgate on January 19, 2010, 11:30:44 AM
También recomiendo usar say ( ) para ver por consola los valores del identificador de fichero y alguna cosilla más de interés, no vaya a ser que estás currando con un identificador no válido porque escribiste mal el nombre o cualquiera de esos fallos que nos hacen sufrir tanto y al final son simple burrería nuestra :D
He comprobado el id de fichero, la posicion de lectura a principio, lo que ocupa el fichero etc.. nada me da una pista de lo que puede ser:(

He pensado que podría ser que guardase mal algun dato dentro de la estructura, pero entonces el programa debería quejarse y no dice ni pio...

Sigo investigando.. os mantendre informados!