использование fread для чтения в буфер int

#c #c #buffer #fread

#c #c #буфер #fread

Вопрос:

Я хотел бы знать, могу ли я использовать fread для чтения данных в целочисленный буфер. Я вижу, что fread() принимает void * в качестве первого параметра. Так что, я не могу просто передать целочисленный буфер (typecast в void *), а затем использовать это, чтобы прочитать, сколько байтов я хочу из файла, если буфер достаточно большой?

т.е. я не могу:

   int buffer[10];
  fread((void *)buffer, sizeof(int), 10, somefile);
  // print contents of buffer
  for(int i = 0; i < 10; i  )
  cout << buffer[i] << endl;
  

Что здесь не так?

Спасибо

Комментарии:

1. Вы пробовали это сделать? Какое поведение вы видите?

2. ДА. Я сделал. Я пробовал много разных вещей! но все время печатаются какие-то большие целые числа, которых нет в файле! они также не похожи на адреса. Такие номера, как: 889860408 906639670 822751544 170997553 875901745 875704842 909249077 839530032

3. Предоставленный код действителен. Однако следует провести дополнительные проверки на fread. Более того, проблема, вероятно, заключается в том, какие данные у вас на самом деле есть в файле.

Ответ №1:

Это должно сработать, если вы записали целые числа в файл, используя что-то вроде fwrite («двоичная» запись). Если файл доступен для чтения человеком (вы можете открыть его с помощью текстового редактора и увидеть числа, которые имеют смысл), вы, вероятно, захотите fscanf / cin .

Ответ №2:

Как упоминали другие, fread должен иметь возможность делать то, что вы хотите, при условии, что входные данные представлены в двоичном формате, который вы ожидаете. Одно предостережение, которое я бы добавил, заключается в том, что код будет иметь зависимости от платформы и не будет функционировать корректно, если входной файл перемещается между платформами с целыми числами разного размера или разными порядковыми номерами (sp).

Кроме того, вы всегда должны проверять возвращаемые значения; fread может завершиться ошибкой.

Ответ №3:

Да, вы можете использовать fread для чтения в массив целых чисел

 int buffer[10]; 

size_t readElements = fread((void *)buffer, sizeof(int), 10, somefile); 

for(int i = 0; i < readElements; i  ) 
   cout << buffer[i] << endl
  

Вы можете проверить количество элементов, которые fread возвращает для печати.

РЕДАКТИРОВАТЬ: при условии, что вы читаете из файла в двоичном режиме, и значения были записаны так, как указано в cnicutar с помощью fwrite .

Комментарии:

1. Нет. Он по-прежнему выводит странные числа. Которых нет в файле !

Ответ №4:

Я пытался сделать то же самое и получал тот же результат, что и ваш, большое значение int при попытке прочитать целое число с помощью fread() файла и, наконец, понял причину этого. Итак, предположим, что ваш входной файл содержит только:

  1. « 5 «
  2. « 5 5 5 «

Подробности, которые я получил от http://www.programmersheaven.com/mb/beginnercpp/396198/396198/fread-returns-invalid-integer /

fread() считывает двоичные данные (даже если файл открыт в текстовом режиме). Число 540352565 в шестнадцатеричном 0x20352035 формате — 0x20 это ASCII-код пробела и 0x35 ASCII-код a '5' (они расположены в обратном порядке, потому что используется машина с начальным порядком).

Итак, что fread делает, это считывает коды ASCII из файла и создает из него int, ожидая двоичных данных. Это должно объяснить поведение при чтении '5 5 5' файла. То же самое происходит при чтении файла с помощью одного '5' , но только один байт может быть прочитан (или два, если за ним следует новая строка) и fread должен завершиться неудачей, если он считывает меньше sizeof(int) байтов, что 4 (в данном случае).

Комментарии:

1. Более или менее… fread() считывает байты (которые не обязательно должны быть кодами ASCII, поскольку ASCII был 7-разрядной системой, а байты обычно (по сути, всегда) являются 8-разрядными величинами). И затем, когда эти байты интерпретируются как целое число, вы получаете результат, который вы описываете (на машине с малым порядком деления). Если двоичные данные не были записаны fwrite() на машине, достаточно похожей на ту, на которой вы читаете данные, нет оснований предполагать fread() , что данные будут иметь смысл.

Ответ №5:

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

Пожалуйста, обратите внимание, что следующий код НЕ содержит надлежащих проверок и МОЖЕТ привести к сбою, если файл не существует, не осталось памяти, нет прав и т. Д. В коде должна быть добавлена проверка для каждой операции открытия, закрытия, чтения, записи.

Более того, я бы выделял буфер динамически.

 int* buffer = new int[10];
  

Это потому, что я не чувствую себя хорошо, когда обычный массив берется в качестве указателя. Но неважно. Пожалуйста, также обратите внимание, что для экономии места следует использовать правильный тип (uint32_t, 16, 8, int, short …) в соответствии с диапазоном чисел.

Следующий код создаст файл и запишет туда правильные данные, которые вы сможете затем прочитать.

     FILE* somefile;
    somefile = fopen("/root/Desktop/CAH/scripts/cryptor C  /OUT/TOCRYPT/wee", "wb");

  int buffer[10];
  for(int i = 0; i < 10; i  )
    buffer[i] = 15;

  fwrite((void *)buffer, sizeof(int), 10, somefile);
  // print contents of buffer
  for(int i = 0; i < 10; i  )
  cout << buffer[i] << endl;

  fclose(somefile);

    somefile = fopen("/root/Desktop/CAH/scripts/cryptor C  /OUT/TOCRYPT/wee", "rb");

  fread((void *)buffer, sizeof(int), 10, somefile);
  // print contents of buffer
  for(int i = 0; i < 10; i  )
  cout << buffer[i] << endl;

  fclose(somefile);