Я немного запутался с функцией fsetpos в библиотеке stdio.h. Я хочу записывать в разные индексы (т.е. не хочу записывать в файл непрерывно) в файл. Я подумывал об использовании fsetpos, однако в документации говорится
The internal file position indicator associated with stream is set to the position
represented by pos, which is a pointer to an fpos_t object whose value shall have been
previously obtained by a call to fgetpos.
Мне не имеет смысла, что я должен установить позицию на основе вызова из fgetpos. Какой смысл, поскольку он просто установит его в положение, в котором он уже установлен. Или я не правильно понимаю?
Из стандарта С11, fseek
имеет аналогичное ограничение:
Для текстового потока, либо
offset
должно быть ноль, илиoffset
должно быть значением, возвращенным ранее успешным вызовомftell
функция в потоке, связанном с тем же файлом иwhence
должен бытьSEEK_SET
Причина в том, что текстовые потоки не имеют однозначного сопоставления между фактическими байтами источника и байтами, которые вы получили бы fgetc
; например в системах Windows символ новой строки в C, как правило, переводится в последовательность из двух двоичных символов: возврат каретки, затем перевод строки.
Следовательно, идея произвольного позиционирования текстового потока на основе числового индекса таит в себе сложности и неожиданности.
На самом деле, документация ftell
предупреждает
Для текстового потока его индикатор положения файла содержит неопределенную информацию, используемую
fseek
функция для возврата указателя положения файла для потока в его положение во времяftell
вызов; разница между двумя такими возвращаемыми значениями не обязательно является значимым показателем количества написанных или прочитанных символов.
Двоичные потоки не имеют этого ограничения, хотя
Бинарный поток не нуждается в значительной поддержке
fseek
звонки со значением откудаSEEK_END
Выше предполагается, что вы работаете с байтовыми потоками. Широко ориентированные потоки имеют дополнительные ограничения. например под Streams
:
Двоичные широко ориентированные потоки имеют ограничения позиционирования файла, приписываемые как текстовым, так и двоичным потокам.
а также
Для широко ориентированных потоков после успешного вызова функции позиционирования файла, которая оставляет индикатор положения файла до конца файла, функция вывода широких символов может перезаписывать частичный многобайтовый символ; любое содержимое файла, кроме записанных байтов, отныне не определено
fsetpos
делает больше, чем просто устанавливает положение файла: снова из стандарта C11:
fsetpos
функция устанавливаетmbstate_t
объект (если есть) и индикатор положения файла
что делает его более подходящим для постановки позиции в широко ориентированных потоках.