Советы с хлебом - PullRequest
       29

Советы с хлебом

0 голосов
/ 19 января 2020

[закрыто, старая тема]

Спасибо

Ответы [ 2 ]

0 голосов
/ 20 января 2020

Я думаю, что вы делаете свой код более сложным, чем необходимо для данной спецификации. Конечно, после fclose(f) вы не можете ожидать ничего полезного от fread(file, 4, 1, f) - если бы вы проверили возвращаемое значение, это было бы 0, указывающее на ошибку.

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

#include <stdio.h>

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s file\n", argv[0]);
        return -1;
    }
    FILE *fp = fopen(argv[1], "rb");
    if (!fp)
    {
        fprintf(stderr, "%s: failed to open file %s for reading\n", argv[0], argv[1]);
        return -1;
    }

    unsigned char data[4];
    size_t offset;
    for (offset = 0; fread(data, sizeof(data), 1, fp) == 1; offset += sizeof(data))
    {
        printf("0x%.4zX: 0x%.2X%.2X%.2X%.2X\n", offset, data[0], data[1], data[2], data[3]);
    }
    printf("0x%.4zX\n", offset);

    fclose(fp);
    return 0;
}

При компиляции из fread53.c в программу fread53 и запускает ее Собственный исполняемый файл выдает:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes \
>     fread53.c -o fread53 
$ fread53 fread53
0x0000: 0xCFFAEDFE
0x0004: 0x07000001
0x0008: 0x03000080
0x000C: 0x02000000
0x0010: 0x11000000
0x0014: 0x98050000
0x0018: 0x85002000
0x001C: 0x00000000
0x0020: 0x19000000
0x0024: 0x48000000
…
0x32AC: 0x34737476
0x32B0: 0x74343276
0x32B4: 0x30303030
0x32B8: 0x30676E2F
0x32BC: 0x542F2F63
0x32C0: 0x634D3464
0x32C4: 0x6651542E
0x32C8: 0x6F005F6D
0x32CC: 0x61696E00
0x32D0
$

Тестирование проводилось на Mac c, работающем под управлением MacOS Catalina 10.15.2 с G CC 9.2.0 и XCode 11.3.1.

0 голосов
/ 19 января 2020

По возможности следует избегать поиска конца файла, чтобы узнать его длину, поскольку это делает вашу программу невозможной для использования с конвейерным вводом.

Скорее, рассмотрите возможность считывания кусками многих 4-байтовых объектов на вызов. Это уменьшает накладные расходы на чтение и позволяет использовать каналы. fread сообщит вам, когда он достигнет конца ввода, вернув меньше элементов, чем запрошено.

#include <stdint.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
  FILE *f = fopen(argv[1], "rb");
  if (!f) return -1;
  const int chunk_size = 1000;
  uint32_t buf[chunk_size]; // a chunk of data read from the input in one fread()
  size_t n_read;
  do {
    n_read = fread(buf, sizeof buf[0], chunk_size, f);  // reads a chunk of ints
    for (int i = 0; i < n_read; ++i) printf("%u\n", buf[i]); // prints what was read
  } while (n_read == chunk_size); // stops when end of input is reached
  return 0;
}
...