Ver la versión completa : recuperar una matriz en un fichero binario
Hola, con un primer programa guardo un archivo binario que posee esta estructura:
num_graf ancho alto y una matriz, el problema reside a al hora de recuperar la matriz
que en algunas posicones como en la [87,0] me empieza a poner valores distintos
a la matriz guardada (lo más seguro esk sean valores basura) y no se a que se puede
deber ya que compruebo la matriz antes de guardarla que sea correcta, aquí les dejo el
código por si alguien sabe que puede ser.
Muchas gracias
// creo el contenido del mapa
/* __________________________________________________ _________________________*/
// guardo el mapa
short int num_graf;
int ancho, alto;
short int **mapa;
string fichero;
ofstream of;
// .......................... (comandos)
of.open(fichero.c_str());
of.write(reinterpret_cast<char*>(&num_graf), sizeof(short int));
of.write(reinterpret_cast<char*>(&ancho), sizeof(int));
of.write(reinterpret_cast<char*>(&alto), sizeof(int));
for(int x=0; x<alto; x++)
of.write(reinterpret_cast<char*>(mapa[x]) , sizeof(short int)*ancho);
/* __________________________________________________ _________________________*/
// recuperar mapa
void Escenario::Inicializar(char* file_mapa, char* file_tipo){
ifstream fi, fi_tipo;
fi.open(file_mapa);
fi_tipo.open(file_tipo);
// comprobar si hay errores
if(fi.fail() || fi_tipo.fail())
cout<<"error al abrir el fichero "<<cerr<<endl;
fi.read(reinterpret_cast<char*>(&num_graf), sizeof(short int));
fi.read(reinterpret_cast<char*>(&ancho), sizeof(int));
fi.read(reinterpret_cast<char*>(&alto), sizeof(int));
// reservo memoria matriz del mapa
mapa = new short int*[alto];
for(int i=0; i<alto; i++)
mapa[i] = new short int[ancho];
// reservo memoria para la matriz de las colisiones
tipo = new int*[num_graf];
for(int i=0; i<num_graf; i++)
tipo[i] = new int[4];
for(int i=0; i<alto; i++)
fi.read( reinterpret_cast<char*>(mapa[i]) , sizeof(short int)*ancho);
for(int i=0; i<num_graf; i++)
fi_tipo.read(reinterpret_cast<char*>(tipo[i]) , sizeof(int)*4);
fi.close();
fi_tipo.close();
// cargo los gráficos
Cargar_Fondo2(grafico, num_graf);
};
/* __________________________________________________ _________________________*/
Haz una prueba con un mapa de 2x2, asi te sera mas facil buscar los fallos.
DarkDijkstra
31/08/2007, 22:30
Se que es una pregunta tonta y obvia, pero más de una vez me ha pasado por despistado... ¿cierras correctamente los ficheros y tal al escribir, verdad?
incluso prueba a hacer un fi.flush() entre cada iteración del bucle de escritura para forzarla...
aunque lo mejor es, para ver si el problema está en la escritura o en la lectura, prueba a escribir una matriz que sean todo 49's (por ejemplo, para que luego veas 1's) y la abres con un editor de textos o algo y mira que pinta tiene, si en algún momento ves que cambian los números es que algo falla al escribir...
Si estas grabando datos en binario, lo mejor es usar un editor de ficheros, esos que ves a la izquierda los valores en hexadecimal y a la derecha el caracter que le corresponde.
Sobre el flush(), con hacerlo antes de cerrar el fichero es suficiente.
DarkDijktra, me encanta tu firma, real como la vida misma. :D
DarkDijkstra
31/08/2007, 22:54
Tienes razon en las tres cosas... lo del editor hexadecimal de ficheros es mas "profesional", aunque para ver simplemente si el fichero sale "raro" te vale cualquier editor. Lo del flush, haciendo un fi.close() incluso ni haría falta... es una manía que tengo yo desde que hice una clase para ir guardando un log de la apliación y hasta que no hice que "flusheara" despues de cada nueva línea me dio algun problema.
Y si, yo creo que es lo mejor que he visto de dilbert... la vi en el trabajo, levanté la vista, vi a mi jefe al fondo y no pude contenerme la risa XD
Tienes razon en las tres cosas... lo del editor hexadecimal de ficheros es mas "profesional", aunque para ver simplemente si el fichero sale "raro" te vale cualquier editor. Lo del flush, haciendo un fi.close() incluso ni haría falta... es una manía que tengo yo desde que hice una clase para ir guardando un log de la apliación y hasta que no hice que "flusheara" despues de cada nueva línea me dio algun problema.
Y si, yo creo que es lo mejor que he visto de dilbert... la vi en el trabajo, levanté la vista, vi a mi jefe al fondo y no pude contenerme la risa XD
Je, je, a mí me pasó eso con esta otra:
http://img396.imageshack.us/img396/4027/dilbertmalvame4.th.gif (http://img396.imageshack.us/my.php?image=dilbertmalvame4.gif)
me he descargado el editor binario HHD software free hex editor y por lo k veo no hay nada raro, puede ser que haya que meterle alguna opción a la hora de abrir el fichero .open(<file>, rb) o algo así?????
he probado con una matriz de 3x2 pero no me ha hecho nada raro, alguna ideilla más????
< - >
me he dado cuenta que cada vez toman valores distintos, y es a partir de la fila 87 (tiene 100 filas) debe de haber alguna zona que no llegue a recorrer
< - >
en la lectura del fichero he añadido:
/*_________________________________________________ __*/
for(int i=0; i<alto; i++){
fi.read( reinterpret_cast<char*>(mapa[i]) , sizeof(short int)*ancho);
if(fi.gcount()!=sizeof(short int)*ancho)
cout<<"Error en la lectura del escenario fila: "<<i<<endl;
}
/*_________________________________________________ __*/
y resulta que las últimas filas de la matriz no me lee los byte correspondientes
hay alguna forma de saber porque da este error??? algo estilo SDL_GetError(), ahhhh y una función que haga lo mismo que 'gcount' pero con un flujo de salida, para saber cuantos byte he escrito en el fichero
Gracias
DarkDijkstra
01/09/2007, 12:47
Que yo recuerde no tienes un gcount en los ofstreams, pero puedes intentar algo con tellp, que te devuelve un long con la posicion actual del "cursor" de escritura tras la ultima operación.
Asi, en cada iteración, sumale a una variable el tamaño que hayas escrito y compáralo con lo que te devuelva tellp.
Otra opción es simplemente mirar el tamaño del fichero resultante, eso si, si estas en windows, al darle a propiedades a un fichero mira el "Tamaño", no el "Tamaño en disco" para verlo.
Lo del editor de texto lo decia simplemente porque si creas una matriz que tenga el mismo valor en todas partes, luego la escribes a disco y abres ese fichero con un editor de texto normal, deberias ver un monton de caracteres iguales (menos al principio, claro, que guardas las tres variables). Si en algun punto ves que cambia, es que se ha escrito mal.
Tambien prueba a, al leer de disco, inicializar la matriz a cero por ejemplo (un valor diferente a lo que hayas puesto en la matriz a la hora de guardarla). Si ves que tras cargar, en algunas partes de la matriz hay valores cero, el problema es al cargar, si hay otro valor (diferente al que pusiste en la matriz a la hora de escribir en disco) el problema esta al grabar.
Hola, he añadido a la escritura del archivo esto:
/*_______________________________________________*/
for(int x=0; x<alto; x++){
of.write(reinterpret_cast<char*>(mapa[x]), sizeof(short int)*ancho);
byte_leidos += sizeof(short int)*ancho;
if(byte_leidos!=of.tellp()){
perror("Error escribir");
cout<<"fila del escenario: "<<x<<endl;
byte_leidos = of.tellp(); // para igualarlo y comprobar los siguientes
}
}
/*_______________________________________________*/
y el resultado que obtengo es que en los valores que me falla la lectura me falla en la escritura ( se escriben menos byte de los que debería escribir) el caso es que el mensaje de 'perror("Error escribir");' me dice que 'no error' he estado comprobando que la matriz a escribir esté bien, no se que puede fallar, he probado este programa con .net y no me sale ningún tipo de error, pero como sizeof(short int) cambia de un compilador a otro el fichero generado no me sirve.
¿ qué me puede estar pasando?
DarkDijkstra
01/09/2007, 21:42
Todo empieza a apuntar a un rayo cósmico o expediente X similar... XD
creo que lo que toca es "debuggear" el código, parar la ejecución en el momento en que comience a escribir mal (o deje de escribir, vamos) e intentar ver que está pasando... ahora mismo no se me ocurre que puede ser.
Si quieres pásame el código y lo pruebo en linux (asumiendo que lo estás probando en visual studio o similar) y te comento (prometo no robarte el codigo ; )
Que no se te olvide de abrir el fichero usando "wb" y "rb" (con la fstream no me acuerdo si se usan otros valores)para decir que es en binario, o puedes tener problemas.
Por ejemplo, en modo texto en cuanto se encuentre con un '\0' (byte 0), lo interpretara como final del fichero, ademas un '\n' (byte 0xa)te escribira 2 bytes...
¿Por qué no pruebas a escribirlo al revés? Es decir, invirtiendo los bucles.
Si al hacerlo así te sigue poniendo mal los mismos valores de las mismas coordenadas de la matriz, entonces es un problema de corrupción de memoria o desbordamiento. Si no, a lo mejor encuentras otras pistas.
ya he conseguido arreglarlo, se ve que es por que a la hora de abrir el fichero no he especificado nada y tenía que poner rb,
MUCHAS GRACIAS A TODOS
XD
DarkDijkstra
05/09/2007, 16:47
y el ganador... swapd0! XD
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.