Discussion:
Volcado de fichero hexa a texto
(demasiado antiguo para responder)
papapep
2003-11-07 13:29:32 UTC
Permalink
Tengo unos ficheros binarios en hexa y necesito acceder a los datos en
ellos almacenados. He adaptado un ejemplillo que encontré en un libro
para empezar a hacer pruebas, pero me sucede lo siguiente:

En el fichero original, visualizado con un editor hexadecimal, me
aparecen los siguientes registros (pongo sólo los 2 primeros como ejemplo):

1) 08 16 01 09 20 03 A6 00 00 00 00 00 00 00 00 00 00 00 CF C0
2) 08 16 01 09 20 03 00 10 00 00 00 00 41 41 00 5A 14 89 1C F0

Y en cambio, el resultado del código es el siguiente:

1) 08-16-01-09-20-03-FFA6-00-00-00-00-00-00-00-00-00-00-00-FFCF-FFC0
2) 08-16-01-09-20-03-00-10-00-00-00-00-41-41-00-5A-14-FF89-1C-FFF0
(LOS GUIONES LOS HE PUESTO YO PARA CLARIFICAR LA SEPARACION DE LOS BYTES).

Como podéis ver en el registro 1 en el byte 6, 19 y 20 y en el registro
2 en los bytes 18 y 20, aparecen FF's que no sé ni porqué salen ni como
evitarlo. En otros registros salen en otra posición, sin pauta ninguna.

Os paso el código por si veis alguna estupidez (cosa que no sería
rara... ;-))

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#define SIZE 128

void display(int numread);
char buf[SIZE];

main(int argc, char *argv[])
{
FILE *fp;
int sector, numread;
if (argc!=2)
{
printf("descripció: 218 NomArxiu\n");
exit(1);
}
if ((fp=fopen(argv[1], "rb"))==NULL)
{
printf("no es pot obrir l'arxiu\n");
exit(1);
}
do
{
printf("Introdueix el sector (-1 per a sortir): ");
scanf("%ld", &sector);
if (fseek(fp, sector*SIZE, SEEK_SET)) /* SEEK_SET és l'offset desde
l'inici del fitxer */
{
printf("Error de seek\n");
}
if ((numread=fread(buf, SIZE, 1, fp))!=SIZE)
{
printf("S'ha arribat a EOF\n");
}
display (numread);
}
while (sector>=0);
}

void display(int numread)

{
int i, j;
for(i=0; i<=numread/20; i++)
{
for(j=0;j<20; j++) printf ("%02X-", buf[i*20+j]);
printf("\n");
}
}


Gracias por vuestra atención.

Josep Sànchez
David Joaquín
2003-11-07 14:57:41 UTC
Permalink
Post by papapep
Tengo unos ficheros binarios en hexa y necesito acceder a los datos en
ellos almacenados. He adaptado un ejemplillo que encontré en un libro
En el fichero original, visualizado con un editor hexadecimal, me
1) 08 16 01 09 20 03 A6 00 00 00 00 00 00 00 00 00 00 00 CF C0
2) 08 16 01 09 20 03 00 10 00 00 00 00 41 41 00 5A 14 89 1C F0
1) 08-16-01-09-20-03-FFA6-00-00-00-00-00-00-00-00-00-00-00-FFCF-FFC0
2) 08-16-01-09-20-03-00-10-00-00-00-00-41-41-00-5A-14-FF89-1C-FFF0
(LOS GUIONES LOS HE PUESTO YO PARA CLARIFICAR LA SEPARACION DE LOS BYTES).
Como podéis ver en el registro 1 en el byte 6, 19 y 20 y en el registro
2 en los bytes 18 y 20, aparecen FF's que no sé ni porqué salen ni como
evitarlo. En otros registros salen en otra posición, sin pauta ninguna.
Si tienen pauta....fijate bien..... 08-16-01-09-20-03, ¿q tienen estos
numeros en comun? .... ¿Y estos? "FF" - A6...... "FF" - CF - "FF" C0....Lo
ves? NO?...Bueno..Te lo explico, los primeros numero 08-16-01-09-20-03, son
numeros sin signo, enteros positivos,es decir, con el bit mas significativo
a 0, sin embargo los otros, quito el FF a posta, A6-CF-C0, son numeros con
signo negativo, es decir, con el bit mas significativo a 1...No estoy
seguro de esta explicacion q voy a dar pero seguro q esta cerca del asunto.
Pues bien..como consecuencia de esto, debes de explicitamente decirle al
compilador (con operadores cast) q lo q vas a imprimir van a ser numeros
hexadecimales y que no es necesaria q haga extension de signo...Como se
consigue esto...facil.... Te marco la linea.
Post by papapep
Os paso el código por si veis alguna estupidez (cosa que no sería
rara... ;-))
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#define SIZE 128
void display(int numread);
char buf[SIZE];
main(int argc, char *argv[])
{
FILE *fp;
int sector, numread;
if (argc!=2)
{
printf("descripció: 218 NomArxiu\n");
exit(1);
}
if ((fp=fopen(argv[1], "rb"))==NULL)
{
printf("no es pot obrir l'arxiu\n");
exit(1);
}
do
{
printf("Introdueix el sector (-1 per a sortir): ");
scanf("%ld", &sector);
if (fseek(fp, sector*SIZE, SEEK_SET)) /* SEEK_SET és l'offset desde
l'inici del fitxer */
{
printf("Error de seek\n");
}
if ((numread=fread(buf, SIZE, 1, fp))!=SIZE)
{
printf("S'ha arribat a EOF\n");
}
display (numread);
}
while (sector>=0);
}
void display(int numread)
{
int i, j;
for(i=0; i<=numread/20; i++)
{
for(j=0;j<20; j++) printf ("%02X-", buf[i*20+j]);
En este printf se debe poner esto (unsigned char), con esto queda
arreglado.Quedaria asin..

printf("%02X-", (unsigned char) buf[i*20+j]);

Quizas haya otros problemas pero, lo he probado con el DJGPP y
funciona.Alguien q este mas informado del tema y vea otra solucion q lo
diga OÑO! :DDDD..
Post by papapep
printf("\n");
}
}
Gracias por vuestra atención.
Josep Sànchez
Salu2.

DJ.
Fernando Arbeiza
2003-11-07 15:32:57 UTC
Permalink
Post by papapep
1) 08-16-01-09-20-03-FFA6-00-00-00-00-00-00-00-00-00-00-00-FFCF-FFC0
2) 08-16-01-09-20-03-00-10-00-00-00-00-41-41-00-5A-14-FF89-1C-FFF0
(LOS GUIONES LOS HE PUESTO YO PARA CLARIFICAR LA SEPARACION DE LOS BYTES).
Como podéis ver en el registro 1 en el byte 6, 19 y 20 y en el registro
2 en los bytes 18 y 20, aparecen FF's que no sé ni porqué salen ni como
evitarlo. En otros registros salen en otra posición, sin pauta ninguna.
Como ya te han dicho, el problema es que utilizas el tipo char para la
variable buf, y char puede ser con signo o sin signo. Tienes que
declarar char como unsigned char, mejor que utilizar un cast en el
fprintf.

Ahora, si me permites, tengo algún comentario sobre el código que espero
que te resulten útiles.
Post by papapep
#include <stdio.h>
#include <ctype.h>
No veo que utilices ninguna función de ctype.h, así que puedes eliminar
esta línea.
Post by papapep
#include <stdlib.h>
#define SIZE 128
void display(int numread);
char buf[SIZE];
No veo que necesites una variable global. ¿Por qué no pasas buf como
argumento a display:

void display(unsigned char *buf, int numread);
Post by papapep
main(int argc, char *argv[])
Mejor declarar que main devuelva un int. El int implícito se ha
eliminado del C99.

int main(int argc, char *argv[])
Post by papapep
{
FILE *fp;
Aquí debería ir la declaración de buf:

unsigned char buf[SIZE];
Post by papapep
int sector, numread;
numread es la salida de fread, luego mejor si es de tipo size_t. sector
es la entrada de seek, mejor que sea long int:

long int sector;
size_t numread;
Post by papapep
if (argc!=2)
{
printf("descripció: 218 NomArxiu\n");
Si printf no lo utilizas con cadenas de formato, mejor utilizar puts o
fputs. Además, la salida de error, mejor al flujo stderr.

fputs("descripció: 218 NomArxiu\n", stderr);
Post by papapep
exit(1);
El valor más portable para indicar error es EXIT_FAILURE:

exit(EXIT_FAILURE);
Post by papapep
}
if ((fp=fopen(argv[1], "rb"))==NULL)
{
printf("no es pot obrir l'arxiu\n");
exit(1);
fopen asigna la variable errno, así que puedes utilizar perror para más
información:

perror("no es pot obrir l'arxiu");
exit(EXIT_FAILURE);
Post by papapep
}
do
{
printf("Introdueix el sector (-1 per a sortir): ");
Como ya te dije antes, si no lo utilizas con cadenas de formato mejor
fputs. Además, deberías utilizar fflush para que la salida aparezca
antes de scanf:

fputs("Introdueix el sector (-1 per a sortir): ", stdout);
fflush(stdout);
Post by papapep
scanf("%ld", &sector);
No compruebas la salida de scanf. En mi sistema, si introduzco una
palabra en lugar de un número, entra en un bucle infinito.

if (scanf("%ld", &sector) < 1) {
fputs("error en la entrada\n", stderr);
exit(EXIT_FAILURE);
}
Post by papapep
if (fseek(fp, sector*SIZE, SEEK_SET)) /* SEEK_SET és l'offset desde
l'inici del fitxer */
{
printf("Error de seek\n");
}
De nuevo, puedes utilizar perror:

if (fseek(fp, sector * SIZE, SEEK_SET) < 0) {
perror("Error de seek");
exit(EXIT_FAILURE);
}
Post by papapep
if ((numread=fread(buf, SIZE, 1, fp))!=SIZE)
Prefiero utilizar un sizeof, en lugar de 1 para que se vea de donde
viene:

numread = fread(buf, SIZE, sizeof (buf[0]), fp);
if (numread != SIZE) { puts("S'ha arribat a EOF"); }
Post by papapep
{
printf("S'ha arribat a EOF\n");
}
display (numread);
}
while (sector>=0);
}
void display(int numread)
void display(unsigned char *buf, size_t numread) {
Post by papapep
{
int i, j;
for(i=0; i<=numread/20; i++)
{
for(j=0;j<20; j++) printf ("%02X-", buf[i*20+j]);
printf("\n");
}
}
Total, después de estas pequeñas modificaciones, el resultado sería:

/***********************/
#include <stdio.h>
#include <stdlib.h>

#define SIZE 128

void display(unsigned char *buf, size_t numread);

int main(int argc, char *argv[]) {
FILE *fp;
long int sector;
size_t numread;
unsigned char buf[SIZE];

if (argc != 2) {
fputs("descripció: 218 NomArxiu\n", stderr);
exit(EXIT_FAILURE);
}
if ((fp = fopen(argv[1], "rb")) == NULL) {
perror("no es pot obrir l'arxiu");
exit(EXIT_FAILURE);
}

do {
fputs("Introdueix el sector (-1 per a sortir): ", stdout);
fflush(stdout);
if (scanf("%ld", &sector) < 1) {
fputs("error en la entrada\n", stderr);
exit(EXIT_FAILURE);
}
if (fseek(fp, sector * SIZE, SEEK_SET) < 0) {
perror("Error de seek");
exit(EXIT_FAILURE);
}
numread = fread(buf, SIZE, sizeof (buf[0]), fp);
if (numread != SIZE) { puts("S'ha arribat a EOF"); }
display(buf, numread);
} while (sector >= 0);

exit(EXIT_SUCCESS);
}

void display(unsigned char *buf, size_t numread) {
size_t i, j;

for (i = 0; i <= numread / 20; i++) {
for (j = 0;j < 20; j++) { printf("%02X-", buf[i * 20 + j]); }
puts("");
}
}
/******************************/

Un saludo.
--
Fernando Arbeiza <URL: mailto:***@ono.com>
Crea tu propio Linux: <URL: http://www.escomposlinux.org/lfs-es>
papapep
2003-11-10 10:26:46 UTC
Permalink
Bueno, voy a intentar asimilar estos conceptos, a ver si me aclaro.

-*Muchísimas*_ gracias por vuestros consejos y comentarios.

Saludos cordiales.

Josep Sànchez
[papapep]

Loading...