fread завершает чтение в середине при нулевых значениях. Также чтение в мусоре прошлых ожидаемых данных

Я читаю по частям двоичный файл, используя объект FILE на C ++. Вот вызов fseek и соответствующий вызов fread:

fseek(fp, startLocation, SEEK_SET);
fread(data, m_sizeOfData, 1, fp);

m_sizeOfData оказывается целым числом больше 400 тысяч. Похоже, что он должен прочитать все 400 тысяч + байтов из двоичного файла в данные (кстати, это char [m_sizeOfData]), однако он останавливается примерно через 6 или 7 символов на символе Юникода, который просто выглядит как прямоугольник. Я думаю, это может означать нулевое завершение? Я не уверен в этом. Это не относится к каждому фрагменту файла, который я читаю. Большинство из них работают (как правило) правильно.

Почему это может быть и есть ли способ правильно прочитать все данные?

Изменить:

fp определяется как таковой:

FILE* fp;
_wfopen_s(&fp, L"C://somedata.dat", L"rb");

Этот шестнадцатеричный символ блока - это 0x06, за которым следует 0x00.
Данные определяются следующим образом: char * data = new char [m_sizeOfData];

изменить 2:

Я также заметил, что в конец другого файла загружен мусор. Мусор выглядит так:

ýýýý««««««««îþ

Это потому, что он пытается завершить определенное круглое количество байтов?


person Chris    schedule 09.10.2009    source источник
comment
Какое значение возвращает fread? то есть: если вы скажете size_t num_read = fread(...);, что будет num_read после этого?   -  person Laurence Gonsalves    schedule 09.10.2009
comment
Мусор, вероятно, неинициализированная память. Проверьте ответ от camh.   -  person Mark Ransom    schedule 09.10.2009


Ответы (3)


Вы неправильно используете параметры count / size для fread. Поскольку вы читаете байты, второй параметр должен быть равен 1, а третий параметр - count:

fread(data, 1, m_sizeOfData, fp);

Затем вы можете использовать возвращаемое значение fread, чтобы определить, сколько байтов было прочитано. Если вы получаете ожидаемый результат, то можете быть уверены, что читаете все нужные вам данные. В этом случае вы, вероятно, выводите данные неправильно - если вы обрабатываете их как строку с завершающим нулем, то 0x00, который вы видите, будет концом того, что печатается. 0x06, вероятно, является глифом прямоугольника.

person camh    schedule 09.10.2009
comment
Спасибо за ваш ответ. это дает тот же результат. Я полагаю, возможно, что поле Value в отладчике в VS null завершает строку, но я все еще вытаскиваю из него ошибки. Я заметил, что в конце загружаемого другого предмета есть какой-то мусор (ýýýý «« «« «« «« îþ) ». - person Chris; 09.10.2009
comment
Я хотел бы выделить часть этого ответа, используя возвращаемое значение fread - это точно скажет вам, сколько байтов было прочитано из файла. Не доверяйте ничему, кроме этого. - person Mark Ransom; 09.10.2009

Откуда вы знаете, что он останавливается там, где вы говорите? Если вы просто смотрите на результат с помощью строковых функций, все эти строковые функции остановятся на первом нулевом символе - фактические данные могут распространяться намного дальше.

person Mark Ransom    schedule 09.10.2009
comment
Я проверяю данные, переданные в char * от отладчика сразу после вызова fread. - person Chris; 09.10.2009
comment
Тогда не могли бы вы сказать нам шестнадцатеричный эквивалент этого прямоугольного символа? И как узнать, что данные на этом заканчиваются? - person Mark Ransom; 09.10.2009

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

person John La Rooy    schedule 09.10.2009
comment
ФАЙЛ * fp; _wfopen_s (& fp, LC: //myfile.dat, Lrb); это открытие в двоичном режиме, правильно? - person Chris; 09.10.2009
comment
да, b для двоичного. вы можете просмотреть файл в шестнадцатеричном редакторе? - person John La Rooy; 09.10.2009
comment
я могу просмотреть файл в блокноте, хотя у меня нет шестнадцатеричного редактора. - person Chris; 09.10.2009