feof() връща true, когато EOF не е достигнат

Опитвам се да чета от файл с конкретно отместване (опростена версия):

typedef unsigned char u8;
FILE *data_fp = fopen("C:\\some_file.dat", "r");
fseek(data_fp, 0x004d0a68, SEEK_SET); // move filepointer to offset
u8 *data = new u8[0x3F0];
fread(data, 0x3F0, 1, data_fp);
delete[] data;
fclose(data_fp);

Проблемът става, че данните няма да съдържат 1008 байта, а 529 (изглежда произволно). Когато достигне 529 байта, извикванията на feof(data_fp) ще започнат да връщат true.

Също така се опитах да чета на по-малки парчета (8 байта наведнъж), но просто изглежда, че удря EOF, когато все още не е там.

Един прост поглед в шестнадесетичен редактор показва, че има много останали байтове.


person Daniel Sloof    schedule 14.12.2010    source източник
comment
@pmg, използването на malloc/free няма да реши проблема ми, но ти ще угодиш :)   -  person Daniel Sloof    schedule 14.12.2010
comment
в C (не знам C++) бих опитал да отворя файла в двоичен режим   -  person pmg    schedule 14.12.2010
comment
@pmg, по дяволите! беше толкова просто... моля, създайте отговор и аз ще го приема.   -  person Daniel Sloof    schedule 14.12.2010
comment
Какво е при отместване 0x004d0a68 + 529?   -  person Eugen Constantin Dinca    schedule 14.12.2010
comment
+1 за xvi. Редактирате ли и с vi?   -  person pmg    schedule 14.12.2010


Отговори (4)


Отварянето на файл в текстов режим, както правите вие, кара библиотеката да преобразува част от съдържанието на файла в други неща, потенциално задействайки неоправдан EOF или лоши изчисления на отместването.

Отворете файла в двоичен режим, като подадете опцията "b" на извикването fopen

fopen(filename, "rb");
person pmg    schedule 14.12.2010

Файлът записва ли се паралелно от друго приложение? Може би има условие за състезание, така че файлът да завършва там, където четенето спира, когато четенето се изпълнява, но по-късно, когато го инспектирате, останалото е записано. Това също би обяснило случайността.

person unwind    schedule 14.12.2010
comment
не! той беше прочетен от друго приложение, но затварянето му или дори копирането на файла и промяната на пътя ми дава същия резултат... достатъчно странно, че произволното число (529) е едно и също всеки път - person Daniel Sloof; 14.12.2010

Може би това е разликата между текстовия и двоичния файл. Ако сте в Windows, новите редове са CRLF, което е два знака във файла, но се преобразува само в един при четене. Опитайте да използвате fopen(..., "rb")

person Milan Babuškov    schedule 14.12.2010

Не мога да видя връзката ви от работа, но ако компютърът ви твърди, че не съществуват повече байтове, бих повярвал. Защо не отпечатате размера на файла, вместо да правите нещата на ръка в шестнадесетичен редактор?

Освен това би било по-добре да използвате входно/изходно ниво 2, f-извикванията са древна грозота на C, а вие използвате C++, тъй като имате нов.

int fh =open(filename, O_RDONLY);
struct stat s;
fstat(fh, s);
cout << "size=" << hex << s.st_size << "\n";

Сега направете вашето търсене и четене, като използвате I/O повиквания от ниво 2, които така или иначе са по-бързи, и нека да видим какъв е размерът на файла наистина.

person Dov    schedule 14.12.2010
comment
В повечето случаи f-обажданията са по-бързи, защото са буферирани, докато ниското ниво е небуферирано. В този случай обаче това няма значение, тъй като има само едно четене. - person Sergei Tachenov; 14.12.2010
comment
АКО искате скорост, не използвайте стар, кофти C api, в който има слой след слой боклуци. Ако правите много четения, имате нужда от клас на буфериране с висока производителност, да. - person Dov; 14.12.2010