Impressão byte por byte

votos
-3

Eu estou tentando fazer um programa em C que se abre um arquivo e imprime seu byte por byte usando o formato Hexabyte (% 02x) para cada byte.

O resultado deve ser algo como isto:

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

Eu sei que eu quero usar fread para fazer isso, mas eu não tenho certeza por que esta solução não 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 que ele nunca atinge o meu loop while, e por isso nunca imprime nada

Publicado 19/09/2018 em 13:24
fonte usuário
Em outras línguas...                            


3 respostas

votos
1

Mesmo se você corrigir o fseekproblema, você tem outras questões:

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

Note que você não está lendo um único byte de cada vez; você está lendo bytes em strlen(path)pedaços -sized de cada vez.

Você também não está imprimindo o byte (s) que você acabou de ler; você está imprimindo o tamanho do arquivo . Assim, supondo que o tamanho do arquivo é, digamos, 65.536 bytes, você vai obter o resultado

10000 hexabytes
10000 hexabytes
10000 hexabytes
...

65536 / strlen(path)vezes. Eu não acho que isso é o que você quer.

Acho que o que você está indo para algo mais ao longo destas linhas:

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
}

A expressão

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

lê até sizeof buffer(1000, neste caso) bytes de fpe armazena o número realmente ler a bytes_read. Se não tivermos atingido EOF, então imprimir o conteúdo buffer.

Respondeu 19/09/2018 em 14:31
fonte usuário

votos
1

Você busca ao final do arquivo, por isso freadnão terá nada para ler. Você precisa buscar de volta ao começo.

A freadtambém está sendo solicitado a ler o comprimento do caminho, o que parece errado, a forma como o circuito está configurado parece ser para 1 byte de cada 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 procurar novamente após a 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);
}

Você também pode ler 1000 bytes de cada vez (como o bufferé), mas então você precisa de uma segunda volta, ou você pode ler o arquivo inteiro, mas você precisa para alocar dinamicamente o buffer ( buffer = malloc(len);).

Respondeu 19/09/2018 em 13:32
fonte usuário

votos
1

É necessário repor o ponteiro do arquivo para o início do arquivo:

fseek(fp, 0, SEEK_SET);
Respondeu 19/09/2018 em 13:28
fonte usuário

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