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!
En mi manualillo hay varios ejemplos, apartado "Trabajar con ficheros". En la wiki también.
Ok. Ahora miro a ver si lo encuentro y le echo un vistazo!
Gracias!
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.
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...
se guardan variables sean como sean...
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...
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).
cuidado con guardar punteros, ya que por lo general representan datos cargados en memoria que no van a corresponder a otra instancia.
Sí, desde luego nunca guardaría el valor de puntero, en cualquier caso a lo que apunta :S
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!
¿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
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).
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
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!
Bueno, he probado con SAVE y LOAD, intentando guardar individualmente el archivo por separado, y creando una estructura padre que almacena todos los datos a guardar, asi solo guardo un archivo.
Resultado: sigue petando con lo mismo. Cuando modifico un dato del array conflictivo...BOOM! Asi que imagino que no será problema de la escritura de ficheros, sino del array en cuestión, que a saber que problema tiene :(
Seguiré investigando...
K++ Drumpi por la idea. No conocia SAVE y LOAD y puede que me sirvan en un futuro, o ahora mismo si consigo arreglar este tema...
¿Entonces el crash se produce al modificar el array o al escribirlo en fichero?, es un array normal con el tamaño correcto y no accedes a posiciones fuera de él, supongo...
Para solucionar esos problemas de depuración te aconsejo abusar "un poquito de say" y que te muestre por consola lo que va pasando, quizás veas algo fuera de sitio, por ejemplo yo acabo de probar con say que map_get_pixel en posiciones negativas (No existentes) del mapa devuelve siempre blanco xDDD
Quote from: Windgate on January 19, 2010, 01:02:18 PM
¿Entonces el crash se produce al modificar el array o al escribirlo en fichero?, es un array normal con el tamaño correcto y no accedes a posiciones fuera de él, supongo...
Casca al escribirlo en el fichero. Puedo modificarlo lo que quiera, que no da ningun problema. La cosa falla al intentar guardarlo... expediente X!
¿Hay algún puntero en tu mega-estructura?
¿Puedes escribir la misma estructura, con esos distintos valores, en distintos ficheros en el mismo código?
no tendras punteros en las estructuras o datos alocados manualmente?
Quote from: Drumpi on January 19, 2010, 02:24:05 PM
¿Hay algún puntero en tu mega-estructura?
¿Puedes escribir la misma estructura, con esos distintos valores, en distintos ficheros en el mismo código?
He probado a escribir lo mismo en otro fichero y nada, peta igual :(
Quote from: SplinterGU on January 19, 2010, 02:49:15 PM
no tendras punteros en las estructuras o datos alocados manualmente?
Cero punteros. Solo uso uno en una funcion, que no toca nada de estas estructuras.
Mmm alocados manualmente te refieres con mem_alloc()?? No, no uso funciones de memoria en todo el programa.
Me estoy volviendo locoooo
que version de bennu usas?
Quote from: SplinterGU on January 19, 2010, 08:29:56 PM
que version de bennu usas?
Mmm donde puedo mirarlo??
Me instalé el bennupack 1.8 cuando salió, y la version del bdgc y del bdgi es la 1.0.0.1, no se si será eso lo que me preguntas
Cuidado Lou, si ha habido cambio de nombres quizás la 1.8 mantuvo "algo" de la 1.7. Yo he tenido alguna liada (Muchas más bien...) similar. No cuesta mucho desinstalar, asegurar que C:/devBennu ya no existe y volver a instalar... Por ir quitando todos los posibles fallos tontos primero...
Assertion failed: str2, file strings.c, line 520
Me acaba de dar ese error. No se si tendrá algo que ver o a surgido alegremente porque siXD Alguna otra vez me ha dado en la linea 560 creo recordar..
Quote from: Windgate on January 19, 2010, 10:15:50 PM
Cuidado Lou, si ha habido cambio de nombres quizás la 1.8 mantuvo "algo" de la 1.7. Yo he tenido alguna liada (Muchas más bien...) similar. No cuesta mucho desinstalar, asegurar que C:/devBennu ya no existe y volver a instalar... Por ir quitando todos los posibles fallos tontos primero...
He reinstalado la 1.8 hace un momento, pero ahora voy a borrar todos los archivos y a reinstalarlo, a ver que pasa.
Si compilas con la linea de comandos podrás ver los errores que, de otra forma, pasan desapercibidos... aunque no se si el IDE del Bennupack es efectivo capturando esos datos.
¿Strings.c es un fichero de código tuyo?
ahhh, no se que version de bennu tiene bennupack, pero habia un error de este estilo que fue corregido algunas versiones atras...
cuando pasa eso, posiblemente hay conflicto de versiones con la libbgdrtm, posiblemente se estan usando librerias que usan bgdrtm.dll y otras libbgdrtm.dll... o una dll bennu propia (no del producto) que no maneja bien las strings... o tambien algun pise de memoria...
necesitamos mas datos, te sugiero que pongas aqui un codigo que reproduzca el error y actualices bennu a la ultima version.
Bueno, parece que traigo buenas noticias, aunque no me acabo de fiar del todo...XD
Eliminando una redundancia en la estructura, osease, simplificando y quitando una cosa que no necesitaba, parece (y digo pareceXD) que todo carga y guarda bien. El error a desaparecido.
Ahora bien, ha aparecido otro error, que solo sale de vez en cuando...
He seguido el consejo de Splinter y me e bajado la ultima version de Bennu, la que aparece en www.bennugd.org. He borrado todos los archivos que tenia en C:/devbennu/bin, y e pegado los nuevos.
Ahora, a veces al cargar el archivo, o a veces dentro del propio juego sin hacer nada, me peta y me saca por consola el siguiente error:
ERROR: Runtime error - string_alloc: out of memory
Imagino que será por algun conflicto que haya surgido al meter los archivos de la ultima version de bennu, seguire haciendo probatinas a ver si lo soluciono, o s alguien tiene idea de porque puede ser, porfavor no se corte:P
Seguiré haciendo pruebas guardando y cargando, a ver si consigo que pete por algun lado... no me fio de que todo se haya solucionado..XD
Esos problemas de las string siempre los he tenido por mezclar versiones de Bennu... ¿Todas las DLL que usas son de C:/devBennu/bin o tienes algunas dll en el directorio del juego?
Una opción que puedes probar es, con Bennupack desinstalado, tener TODAS las dll y el bgdi, bgdc y compañía en el directorio del juego y arrancar con un .bat como en mi tuto, así aseguras que usas esas .dll y sólo esas .dll
Tranquilo, al final lo solucionarás, tuve una temporada así de cabrona y hasta que no formateé tuve algunos ejemplos que no había forma de hacerlos funcionar, especialmente el de visión por computador me hizo sudar tinta :D
Sigo trabajando con la plantilla de tu tutorial:P tenia el .bat y las dll dentro de la carpeta del juego y nada. He probado desistalando todo, metiendo las dll de la ultima version de Bennu y nada :(
Ademas, no tengo idea de que puede hacer saltar el error, porque salta cuando quiere: nada mas cargar, mientras camino, mientras mato un bicho, mientras no hago nada...
Voy a probar una burradilla, y va a ser poner un say al comienzo de cada proceso, y en su loop, para ver cual es el ultimo en ejecutarse antes de cascar, a ver si saco algo en claro...
Bueno, tras todo el día probando... no he conseguido nada :( asi que me resigno... por ahora.
Voy a seguir con otras cosillas aguantando el maldito error, a ver si trasteando cosillas lo soluciono!
Gracias por vuestra ayuda!
Una pregunta sobre los ficheros...
Son binarios o se pueden trabajar con archivos de texto??
Me interesa leer y guardar archivos que puedan ser procesos luego en cualquier editor de textos...
Se puede trabajar con ficheros de texto, si escribes char en él (1 byte)...
Alguna prueba he hecho, pero hace tanto que ni me acuerdo, inténtalo que en 2 minutos que te pongas lo verás.
Texto, binarios... al fin y al cabo es lo mismo. Tu escribes 32, y luego lo lees: si lo lees como byte, valdrá 32, pero si lo lees como caracter ASCII es un espacio.
Si escribes valores bytes entre 32 y 255 verás los caracteres ASCII con cualquier editor de textos, así de simple.
Si quieres más simpleza a la hora de guardar, mira FPUTS (y FGETS). Ten cuidado porque FPUTS pone un caracter de fin de linea que no se ve "a simple vista", y que windows no lo reconoce como tal (porque es el fin de linea del formato Unix).
que pereza mejor usa xml, o sqlite3 , estan en ejemplos dlls en el bennupack!!!
y puedes leer esto desde algo externo facilmente...
Estas perdiendo tiempo que podrias usar en el juego.
si es para el concurso no vale por no estar en el soporte oficial :D y si es para wiz habría que portar los módulos :D (otra vez)
¿El módulo SQL puede ahorrar tiempo a la hora de guardar datos en fichero? Lo tengo que probar... En mi universidad me enseñaron demasiadas técnicas de la edad media...
Quote from: l1nk3rn3l on February 05, 2010, 03:06:29 PM
que pereza mejor usa xml, o sqlite3 , estan en ejemplos dlls en el bennupack!!!
y puedes leer esto desde algo externo facilmente...
Estas perdiendo tiempo que podrias usar en el juego.
leer XML, que interesante...
buscare esos ejemplo
n.n
grax l1nk3rn3l