[ Foro de C ]

Problemas al leer archivos sin formato

28-May-2009 11:52
Jesús S.
6 Respuestas

¡Hola! He creado un archivo con fichas del tipo struct para clientes de una tienda ficticia. Todo en orden. Hay mezclados datos numéricos y de caracteres y el archivo se crea perfectamente. El problema me llega cuando trato de leer los datos de ese archivo y presentarlos en la pantalla. Los de carácter salen bien, pero los numéricos son un auténtico desbarajuste. Me gustaría enviaros como anexo lo que he preparado para que me pudiéseis comentar lo que he hecho mal, pero soy novato en este foro y no veo la forma de hacerlo. No es que sean ejercicios largos, pero el ponerlos pegados me parece un poco pesado para leer. ¿Cómo podría hacerlo o cómo os podría explicar mejor lo que me pasa? Saludos.
29-May-2009 01:40
Nacho Cabanes (+84)

En cuanto a que el mensaje sea legible, incluso aunque incluya un código fuente, puedes cambiar el "tipo de formato", para que no sea automático sino "texto plano" y así se leerá un poco mejor.

Aun así, lo más recomendable es incluir sólo el fragmento clave del programa dentro del texto del mensaje, para destacar la parte más problemática, e incluir todo el fuente como "archivo adjunto".

Ya sobre tu problema concreto: Dices que usas un struct, pero no cómo guardas los datos del struct en el fichero, ni cómo los lees.

La primera alternativa es guardar con "fprintf" y leer con "fscanf", como puedes ver en el apartado 6.4 del curso, pero tiene problemas como el manejo de espacio ("scanf" y sus derivados terminan la lectura en cuanto encuentran un espacio).

Una alternativa mejor es guardar la ficha (todo el struct) con fwrite y leerlo con fread, como hago en el curso en los ejemplos 6.10 y 6,12. Por ejemplo, la ficha podría ser así:


typedef
   struct                          /*  Nuestro tipo de datos  */
   {
       char nombre[21];           /* 20 letras */
       char direccion[31];        /* 30 letras */
       char ciudad[16];           /* 15 letras */
       char cp[6];                /*  5 letras */
       char telef[13];            /* 12 letras */
       char observ[41];           /* 40 letras */
   }  tipoAgenda;


Cada ficha sería de tipo "tipoAgenda" y tendría una longitud "longFicha":


tipoAgenda ficha;
int longFicha = sizeof (tipoAgenda);


Podrías guardar una ficha con


fwrite( &ficha, longFicha, 1, fichAgenda);


(donde "fichAgenda" es el fichero, claro). Y podrías leer una ficha de cualquier parte del fichero con


fseek( fichAgenda, (numFicha-1)*longFicha, SEEK_SET );
fread( &ficha, longFicha, 1, fichAgenda);


Te adjunto el fuente completo de la agenda, y me lo apunto para incluirlo en la próxima actualización del curso.

Pruebalo, intenta aplicarlo a tu caso, y avisa si tienes dudas.


01-Jun-2009 18:05
Jesús S.

¡Hola! Gracias por la rápida contestación. El programa que utilizo para escribir la agenda va como anexo. Este funciona correctamente. Como no puedo poner dos anexos, enviaré otra contestación aparte para enviar el programa con el que intento leer el archivo. Saludos, Jesús
01-Jun-2009 18:14
Jesús S.

Siguiendo con el mensaje anterior, adjunto envío el programa con el que intento leer y mostrar en pantalla el archivo creado con el otro programa. Los resultados que obtengo son sorprendentes. Si puedo sacar una copia del archivo creado y de los resultados obtenidos, lo pondré en el foro. Podéis crear un archivo con 4 fichas y ver los resultados. No cuesta mucho. ¿Dónde está el fallo?. Saludos, Jesús.
02-Jun-2009 09:15
Jesús S.

¡Hola! He preparado una agenda en binario y me ha quedado muy bien. Tenía un fallo que quizá convendría advertir a los estudiantes para que no lo cometan. Se crea mediante programa un archivo binario, por ejemplo agenda.bin, y para ver lo que está escrito en él lo abro con el block de notas y lo guardo como agenda.old. Este último ya no es un archivo binario sino de texto, lo que provoca el que salgan errores al leerlo, que es lo que me pasaba. Saludos, Jesús
03-Jun-2009 00:02
Nacho Cabanes (+84)

El problema debe estar en la lectura, en el "fscanf", porque usas un formato muy extraño:

fscanf(fpt, " %[^\n]", cliente.nombre);

Por una parte, el [^\n] no es un formato habitual, sino algo más cercano a una expresión regular, que quizá no admita algún compilador. Si quieres leer una línea completa de texto, yo usaría "fgets".

Por otra parte, en la lectura estás esperando que comience por espacio, algo que no garantizas cuando escribes:

- Lees con

fscanf(fpt, " %[^\n]", cliente.nombre);

- Escribes con

fprintf(fpt, "%s\n", cliente.nombre);







03-Jun-2009 00:07
Nacho Cabanes (+84)

En cuanto a la agenda en binario, tienes razón: se puede ver y modificar con un editor hexadecimal, o bien ver pero no modificar con un editor de texto, como el bloc de notas.

El motivo es que la mayoría de editores de texto no son capaces de manejar correctamente ficheros que no sean de texto puro: pueden ignorar ciertos símbolos que corresponden a caracteres de control, o bien reemplazar unos códigos de control por otros (por ejemplo, el carácter de avance de línea de Unix por la pareja de caracteres que se usan en Windows). El resultado normalmente será un fichero alternado, que no será legible por la aplicación original.






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)