cstdio — Разъяснение по fsetpos, переполнение стека

Я немного запутался с функцией 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. Какой смысл, поскольку он просто установит его в положение, в котором он уже установлен. Или я не правильно понимаю?

0

Решение

Из стандарта С11, fseek имеет аналогичное ограничение:

Для текстового потока, либо offset должно быть ноль, или offset должно быть значением, возвращенным ранее успешным вызовом ftell функция в потоке, связанном с тем же файлом и whence должен быть SEEK_SET

Причина в том, что текстовые потоки не имеют однозначного сопоставления между фактическими байтами источника и байтами, которые вы получили бы fgetc; например в системах Windows символ новой строки в C, как правило, переводится в последовательность из двух двоичных символов: возврат каретки, затем перевод строки.

Следовательно, идея произвольного позиционирования текстового потока на основе числового индекса таит в себе сложности и неожиданности.

На самом деле, документация ftell предупреждает

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

Двоичные потоки не имеют этого ограничения, хотя

Бинарный поток не нуждается в значительной поддержке fseek звонки со значением откуда SEEK_END


Выше предполагается, что вы работаете с байтовыми потоками. Широко ориентированные потоки имеют дополнительные ограничения. например под Streams:

Двоичные широко ориентированные потоки имеют ограничения позиционирования файла, приписываемые как текстовым, так и двоичным потокам.

а также

Для широко ориентированных потоков после успешного вызова функции позиционирования файла, которая оставляет индикатор положения файла до конца файла, функция вывода широких символов может перезаписывать частичный многобайтовый символ; любое содержимое файла, кроме записанных байтов, отныне не определено

fsetpos делает больше, чем просто устанавливает положение файла: снова из стандарта C11:

fsetpos функция устанавливает mbstate_t объект (если есть) и индикатор положения файла

что делает его более подходящим для постановки позиции в широко ориентированных потоках.

0

Другие решения


По вопросам рекламы [email protected]