Указатель конца FILE* не равен размеру записанных данных

StackOverflow https://stackoverflow.com/questions/145006

  •  02-07-2019
  •  | 
  •  

Вопрос

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

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.

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

Это было полезно?

Решение

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

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

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

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

Об этом говорится в стандарте C99. 7.19.5.3 The fopen function:

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

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

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

Другие советы

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top