Указатели в C с двоичным файлом - PullRequest
1 голос
/ 06 апреля 2010

Я читаю содержимое файла, используя fread в массив символов. Но я не уверен, почему он не печатается на выходе. Вот код:

void getInfo(FILE* inputFile)
{
   char chunk[4];
   int liIndex;
   for (liIndex = 0 ; liIndex < 4 ; liIndex++)
   {
      fread(chunk, sizeof(char), 4, inputFile);
   }
   printf("\n chunk %s", chunk);
}

Вывод вообще ничего не печатает. Куда я иду не так?

С уважением, Негр

Ответы [ 4 ]

3 голосов
/ 06 апреля 2010

На мой взгляд, fread и fwrite просто добавляют слой путаницы.

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

int ch; 
while ((ch = getc(inputFile)) != EOF)
   putchar(ch); 

Но я думаю, что реальная проблема здесь в том, что вы, возможно, не совсем понимаете, о чем вы просите. Вы читаете двоичные данные, а затем пытаетесь распечатать их как символьные данные; многие произвольные байтовые значения не соответствуют каким-либо печатным символам. Что вы ожидаете увидеть для этих байтов?

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

например,

void func(FILE *s)
{
   int ch;
   while ( (ch = getc(s)) != EOF )
      printf("%d -> %c\n", ch, ch);
}

Когда я запускаю этот фрагмент программы для файла, содержащего один из каждого байта, становится ясно, что многие значения не имеют смысла при интерпретации как символа:

[snip...]
29 ->
30 ->
31 ->
32 ->
33 -> !
34 -> "
35 -> #
36 -> $
37 -> %
38 -> &
39 -> '
[...more snipping]
3 голосов
/ 06 апреля 2010

Переместите printf в цикл. На самом деле, вы печатаете только последний прочитанный фрагмент.

Редактировать: Я прочитал вопрос, но не название, по-видимому. Вам придется сделать это и переключиться на fwrite, как сказал Томас.

2 голосов
/ 06 апреля 2010

Вы не можете распечатать двоичный файл, используя printf. printf будет обрабатывать двоичный двоичный объект как строку с нулевым символом в конце, поэтому любой '\0' байт, который окажется в вашем чанке, завершится "строкой".

Чтобы полностью записать блок в стандартный вывод, используйте fwrite:

fwrite(chunk, sizeof(char), 4, stdout);
1 голос
/ 06 апреля 2010

Немного деконструкции вашего исходного кода:

void getInfo(FILE* inputFile) 
{ 
   char chunk[4]; 
   int liIndex; 
   for (liIndex = 0 ; liIndex < 4 ; liIndex++) 
   { 
      fread(chunk, sizeof(char), 4, inputFile); 

Вы читаете 4 байта за раз, повторяется 4 раза; это означает, что при выходе из цикла вы прочитали 16 байтов, а блок содержит байты 12-16. Это то, что вы хотели? Если вы просто хотите прочитать первые четыре байта, прервите цикл и просто вызовите fread один раз. Если вы хотите прочитать и вывести первые 16 байтов, то вам также необходимо переместить оператор вывода в цикл.

Как уже упоминали другие, не кодируйте 4 жестко; используйте вместо этого sizeof chunk.

   } 
   printf("\n chunk %s", chunk); 
} 

Помните, что спецификатор преобразования %s ожидает, что соответствующий аргумент будет указывать на завершающуюся 0 последовательность печатаемых символов, поэтому chunk[0] - chunk[2] должны быть печатаемыми (то есть isprint(chunk[i]) == 1) и chunk [ 3] лучше всегда быть 0, или вы можете получить какой-то странный вывод. Поскольку в бинарных файлах такая ситуация встречается редко, вы можете изменить способ записи этого вывода.

Вот как можно вывести отдельные байты в виде целочисленных значений:

printf("chunk: ");
for (i = 0; i < sizeof chunk; i++)
  printf("%02x ", chunk[i];
putchar('\n');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...