Impresión byte a byte

votos
-3

Estoy tratando de hacer un programa en C que se abre un archivo e imprime su byte a byte con el formato Hexabyte (% 02x) para cada byte.

El resultado debe ser algo como esto:

$ ./hexabyte file
43
3d
67
...

Yo sé que quiero usar fread para hacer esto, pero no estoy seguro de por qué esta solución no funciona:

#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>


int args_test(int args, char path[]){

  if(args < 1){
    fprintf(stderr, Usage: %s path\n, path);
    exit(EXIT_SUCCESS);
  }
  if(args < 2){
    fprintf(stderr, Usage: %s path\n, path);
    exit(EXIT_SUCCESS);
  }

  if(args > 2){
    fprintf(stderr, Usage: %s path\n, path);
    exit(EXIT_SUCCESS);
  }

  return 0;
}


int open_file(char path[]){
  FILE *fp;
  fp = fopen(path, r);
  char buffer[1000];

  if(!fp){
    fprintf(stderr, %s\n, strerror(errno));
    return EXIT_FAILURE;
  }

  fseek(fp, 0, SEEK_END);
  int len = ftell(fp);

  //Why does it not reach this loop?
  while (fread(buffer, strlen(path), 1, fp) == 1){
    printf(%02x hexabytes\n, len);
  }

  fclose(fp);

  exit(EXIT_SUCCESS);
}

int main(int args, char* argv[]){
  if(args < 2 || args > 2){
    args_test(args, argv[0]);
  }
  args_test(args, argv[1]);
  open_file(argv[1]);
  exit(EXIT_SUCCESS);
}

Parece como si nunca llega a mi bucle while, y por lo tanto nunca se imprime nada

Publicado el 19/09/2018 a las 13:24
fuente por usuario
En otros idiomas...                            


3 respuestas

votos
1

Incluso si se fija el fseekproblema, tiene otros problemas:

while (fread(buffer, strlen(path), 1, fp) == 1){
  printf("%02x hexabytes\n", len);
}

Tenga en cuenta que usted no está leyendo un solo byte a la vez; estás leyendo bytes en strlen(path)trozos -sized a la vez.

Tampoco se está imprimiendo el byte (s) que acaba de leer; que está imprimiendo la longitud del archivo . Así que asumiendo que su tamaño de archivo es, por ejemplo, 65.536 bytes, obtendrá la salida

10000 hexabytes
10000 hexabytes
10000 hexabytes
...

65536 / strlen(path)veces. No creo que eso es lo que quiere.

Creo que lo que vamos a dar algo más a lo largo de estas líneas:

unsigned char buffer[1000]; // for arbitrary bytes, unsigned char works better.

int bytes_read = 0;

while ( (bytes_read = fread( buffer, 1, sizeof buffer, fp )) != EOF )
{
  for( int b = 0; b < bytes_read; b++ )
  {
    printf( "%02hhx\n", buffer[b] ); // %x expects unsigned *int*, use the
  }                                  // hh modifier to specify unsigned char
}

La expresion

bytes_read = fread( buffer, 1, sizeof buffer, fp )

lee hasta sizeof buffer(1000 en este caso) bytes desde fpy almacena el número leído realmente a bytes_read. Si no hemos golpeado EOF, luego imprimir el contenido de buffer.

Respondida el 19/09/2018 a las 14:31
fuente por usuario

votos
1

Usted buscará el final del archivo, por lo que freadno tendrá nada que leer. Es necesario buscar de nuevo al comienzo.

El freadtambién se le pide que lea la longitud de la ruta, que parece mal, la manera en que su bucle está configurado parece ser de 1 byte a la vez.

fseek(fp, 0, SEEK_END); // Seeks to end of file
int len = ftell(fp);

// Nothing to read, at end
while (fread(buffer, strlen(path), 1, fp) == 1){
    printf("%02x hexabytes\n", len);
}

Basta con buscar de nuevo después de la ftell.

fseek(fp, 0, SEEK_END); // Seeks to end of file
int len = ftell(fp);
fseek(fp, 0, SEEK_SET); // Go to start again
// Read from start, 1 byte at a time
char byte;
while (fread(&byte, 1, 1, fp) == 1){
    printf("%02X\n", (int)byte);
}

También podría leer 1000 bytes a la vez (como su bufferes), pero luego se necesita un segundo bucle, o se puede leer el archivo completo, pero hay que asignar dinámicamente la memoria intermedia ( buffer = malloc(len);).

Respondida el 19/09/2018 a las 13:32
fuente por usuario

votos
1

Es necesario para restablecer el puntero del archivo al principio del archivo:

fseek(fp, 0, SEEK_SET);
Respondida el 19/09/2018 a las 13:28
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more