#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()
файла и, наконец, понял причину этого. Итак, предположим, что ваш входной файл содержит только:
- «
5
« - «
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);