Указатель конца FILE * не равен размеру записанных данных - PullRequest
8 голосов
/ 28 сентября 2008

Проще говоря, у меня есть следующий фрагмент кода:

FILE* test = fopen("C:\\core.u", "w");
printf("Filepointer at: %d\n", ftell(test));
fwrite(data, size, 1, test);
printf("Written: %d bytes.\n", size);
fseek(test, 0, SEEK_END);
printf("Filepointer is now at %d.\n", ftell(test));
fclose(test);

и выводит:

Filepointer at: 0
Written: 73105 bytes.
Filepointer is now at 74160.

Почему это? Почему количество записанных байтов не соответствует указателю файла?

Ответы [ 4 ]

19 голосов
/ 28 сентября 2008

Поскольку вы открываете файл в текстовом режиме, он преобразует маркеры конца строки, такие как LF, в CR / LF.

Это вероятно, если вы работаете в Windows (и, вероятно, если вы, учитывая, что имя вашего файла начинается с "c:\").

Если вы откроете файл в режиме "wb", я подозреваю, что вы обнаружите, что числа идентичны:

FILE* test = fopen("C:\\core.u", "wb");

В стандарте C99 это сказано в 7.19.5.3 The fopen function:

Режим аргумента указывает на строку. Если строка является одной из следующих, файл открыть в указанном режиме. В противном случае поведение не определено.

r открыть текстовый файл для чтения
w усечь до нулевой длины или создать текстовый файл для записи
a append; открыть или создать текстовый файл для записи в конце файла
rb открыть бинарный файл для чтения
wb усечь до нулевой длины или создать двоичный файл для записи
ab append; открыть или создать двоичный файл для записи в конце файла
r+ открыть текстовый файл для обновления (чтение и запись)
w+ усечь до нулевой длины или создать текстовый файл для обновления
a+ append; открыть или создать текстовый файл для обновления, писать в конце файла
r+b или rb+ открытый двоичный файл для обновления (чтение и запись)
w+b или wb+ обрезать до нулевой длины или создать двоичный файл для обновления
a+b или ab+ append; открыть или создать двоичный файл для обновления, записав его в конец файла

Вы видите, что они различают w и wb. Я не верю, что реализация требуется для различного отношения к ним, но обычно безопаснее использовать двоичный режим для двоичных данных.

0 голосов
/ 13 февраля 2010

windows на самом деле не записывает все данные в файл без сброса и, возможно, fsync. Может быть, поэтому

0 голосов
/ 29 сентября 2008

Файловый указатель - это cookie. Это не имеет значения. Единственное, для чего вы можете его использовать, - искать в одном и том же месте файла. Я даже не уверен, гарантирует ли ISO C, что ftell возвращает растущие значения. Если вы не верите этому, пожалуйста, посмотрите на разные режимы поиска (). Они существуют именно потому, что позиция не является простым байтовым смещением.

0 голосов
/ 29 сентября 2008

что возвращает fwrite? обычно возвращаемое значение должно быть числом записанных байтов. Кроме того, что отвечает ftell () прямо перед fseek?

Может помочь узнать, какая операционная система, версия компилятора C и библиотека C.

...