Печать побайтно

голоса
-3

Я пытаюсь сделать программу C, которая открывает файл и выводит его побайтно, используя формат Hexabyte (% 02x) для каждого байта.

Результат должен быть что-то вроде этого:

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

Я знаю, что я хочу использовать Fread, чтобы сделать это, но я не знаю, почему это решение не работает:

#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);
}

Похоже, что он никогда не достигнет моего время цикла, и для этого не печатает ничего

Задан 19/09/2018 в 13:24
источник пользователем
На других языках...                            


3 ответов

голоса
1

Даже если устранить fseekпроблему, у вас есть другие вопросы:

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

Обратите внимание , что вы не читаете один байт за один раз; вы читаете байты в strlen(path)-sized кусков за один раз.

Вы также не печатает байт (ы) вы только что прочитали; вы напечатав длину файла . Так предполагается , что ваш размер файла, скажем, 65536 байт, вы получите выход

10000 hexabytes
10000 hexabytes
10000 hexabytes
...

65536 / strlen(path)раз. Я не думаю, что это то, что вы хотите.

Я думаю, что вы собираетесь что-то больше вдоль этих линий:

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
}

Выражение

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

читает до sizeof buffer(1000 в данном случае) байт от fpи хранит число фактически прочитанного bytes_read. Если мы не попали EOF, то мы выводим содержимое buffer.

Ответил 19/09/2018 в 14:31
источник пользователем

голоса
1

Вы стремитесь к концу файла, так что freadничего не будет читать. Вам необходимо обратиться назад к началу.

freadТакже попросили прочитать длину пути, который , кажется , не так, как ваш цикл устанавливается , как представляется, в течение 1 байт за один раз.

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);
}

Просто искать снова после того , как 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);
}

Вы могли бы также прочитать 1000 байт в то время (как ваш bufferесть) , но тогда вам нужен второй цикл, или вы можете прочитать весь файл, но вам необходимо динамически выделять буфер ( buffer = malloc(len);).

Ответил 19/09/2018 в 13:32
источник пользователем

голоса
1

Вам нужно сбросить указатель файла в начало файла:

fseek(fp, 0, SEEK_SET);
Ответил 19/09/2018 в 13:28
источник пользователем

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