Вопрос по file, fseek, c++, c – fseek не работает при открытии файла в режиме «a» (добавление)

19
FILE* f = fopen("rajat", "w");
fputs("sometext", f);
fseek(f, 6, SEEK_SET);
fputs("is a", f);
fclose(f);

Успешно возвращается: "Someteis a & quot;"

Но

FILE* f = fopen("rajat", "a");
fputs("sometext", f);
fseek(f, 6, SEEK_SET);
fputs("is a", f);
fclose(f);

Не работает. Возвращает & quot; sometextis & quot;

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

Не нужно"w+" для первого? В противном случае файл будет уничтожен и воссоздан. Oliver Charlesworth

Ваш Ответ

1   ответ
26

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

Или, другими словами, чтобы предотвратить потерю данных, положение «указатель записи» переопределяет позицию «указателя чтения». После любого добавления указатель записи возвращается к новомуEOF.

Ответ наэта ссылка ссылается на соответствующий раздел стандарта C.

Использовать"w+" режим, если вы хотите записать в произвольные места в файле. Существующий файл будет перезаписан.

Если вы хотите сначала добавить существующий файл, но потомfseek в произвольное место, используйте"r+" с последующимfseek(f, 0, SEEK_END).

Я всегда обнаруживал, что поведение"a" быть неинтуитивным.
@JamesKanze Это правильно, я уточнил этот момент в редактировании несколько минут назад. Недостаток дляr+ в том, что файл должен существовать, хотя.
Если вы не хотите, чтобы существующие данные в файле были уничтожены, вы должны использовать"r+"не"w+".
@MichaelBurr Поведение"a" предназначен для поддержки таких вещей, как файлы журналов, которые (или могут быть) записаны из нескольких разных процессов. Стремление к концу должно быть атомарным (если это возможно); на платформе Unix файл будет открыт с"O_APPEND" флаг. Затем пользовательский код гарантирует, что поток имеет достаточно большой буфер, выводит запись журнала и вызываетfflush написать это.
@LaurieStearn Звучит как хорошее предложение по редактированию. Нажмите & quot; предложить изменить & quot; ссылку и редактировать ответ; Я буду рад принять ваше изменение. Спасибо!

Похожие вопросы