Что делает fseek?

Я новичок в C и использую fseek. Мой вопрос в том, что именно он делает?

например: fseek(FILE *stream, -1, SEEK_CUR) будет читать 1 символ назад, так что это уже в конце файла?

Значит ли это, что fseek(FILE *stream, 0, SEEK_CUR) ничего не делает?

И как нам применить функции после fseek к структуре данных?


person No_Name    schedule 11.02.2021    source источник
comment
fseek не read 1 character backwards. Он ничего не читает; он просто устанавливает позицию в файле.   -  person William Pursell    schedule 11.02.2021
comment
Есть некоторые побочные эффекты, так что fseek(..., 0, SEEK_CUR) не бесполезен. Но это не меняет положение в файле.   -  person William Pursell    schedule 11.02.2021


Ответы (1)


Я новичок в C и использую fseek. Мой вопрос в том, что именно он делает?

fseek устанавливает индикатор позиции файла для потока, на который указывает stream. Новая позиция будет задана смещением вместе с флагом:

  • Для SEEK_SET смещение относительно начала файла.

  • Для SEEK_CUR смещение относительно текущего положения индикатора.

  • Для SEEK_END это относительно конца файла.

например: fseek(FILE *stream, -1, SEEK_CUR) будет читать 1 символ назад, так что это уже в конце файла?

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

Он не читает символы, как указано, он позиционирует индикатор в желаемую позицию по смещению от его текущей позиции, как описано выше.

Значит ли это, что fseek(FILE *stream, 0, SEEK_CUR) ничего не делает?

С практической точки зрения он ничего не делает видимым, поскольку смещение равно 0, индикатор не перемещается, а просто размещается в том же положении. Он очищает статус конца файла (сбрасывает флаг EOF как упоминается @rici).

Из C11 N1570 §7.21.9.2

#include <stdio.h>
int fseek(FILE *stream, long int offset, int whence);

Описание:

2 Функция fseek устанавливает индикатор позиции файла для потока, на который указывает stream. Если возникает ошибка чтения или записи, для потока устанавливается индикатор ошибки и fseek завершается ошибкой.
3 Для двоичного потока новая позиция, измеренная в символах от начала файла, получается путем добавления смещения к положению, указанному whence. Указанная позиция является началом файла, если whence равно SEEK_SET, текущим значением индикатора позиции файла, если SEEK_CUR, или концом файла, если SEEK_END. Двоичный поток не обязательно поддерживает вызовы fseek со значением whence, равным SEEK_END.
4 Для текстового потока либо offset должно быть равно нулю, либо offset должно быть значением, возвращенным предыдущим успешным вызовом. к функции ftell в потоке, связанном с тем же файлом, и whence должно быть SEEK_SET.
5 После определения новой позиции успешный вызов функции fseek отменяет любые эффекты функции ungetc в потоке, очищает индикатор конца файла для потока, а затем устанавливает новая позиция. После успешного вызова fseek следующая операция над потоком обновления может быть либо вводом, либо выводом.

Возвраты:

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

person anastaciu    schedule 11.02.2021
comment
fseek(stream, 0, SEEK_CUR) сбрасывает флаг EOF. Это не самый простой способ сделать это, но он делает это. (Полезно, если вы пишете что-то вроде tail -f.) Во многих системах (например, Linux) он также позволяет узнать, можно ли искать stream, но я не думаю, что такое поведение гарантируется каким-либо стандартом. - person rici; 11.02.2021
comment
@rici, правильно, он очищает статус конца файла. Может быть, побочные эффекты, о которых упоминает Уильям Перселл. - person anastaciu; 11.02.2021
comment
@anastaciu, значит, fseek просто указывает на позицию в структуре данных? Может ли для чтения символа в файле быть fscanf альтернативой fseek? - person No_Name; 11.02.2021
comment
@No_Name, это заставляет индикатор указывать на некоторую позицию в потоке, следующие чтения, выполняемые какой-либо функцией чтения (например, fscanf), будут выполняться с этой точки, fscanf фактически считывает содержимое потока и продвигает позицию индикатора к точка, где чтение останавливается, они не делают одно и то же, хотя вы можете использовать fscanf для продвижения индикатора на количество прочитанных байтов, но если цель состоит в том, чтобы просто переместить индикатор, правильный инструмент - fseek. - person anastaciu; 11.02.2021