Использование fseek с указателем файла, указывающим на stdin

в зависимости от аргументов командной строки Я устанавливаю указатель файла, чтобы указать либо на указанный файл, либо на stdin (для целей конвейера). Затем я передаю этот указатель на несколько различных функций для чтения из файла. Вот функция для получения указателя файла:

FILE *getFile(int argc, char *argv[]) {
    FILE *myFile = NULL;
    if (argc == 2) {
        myFile = fopen(argv[1], "r");
        if (myFile == NULL)
           fprintf(stderr, "File "%s" not foundn", argv[1]);
    }
    else
        myFile = stdin;
    return myFile;
}

, когда он указывает на stdin, fseek не работает. Под этим я подразумеваю, что использую его, а затем использую fgetc и я получаю неожиданные результаты. Это ожидаемое поведение, и если да, как мне перемещаться в разные места потока?

например:

int main(int argc, char *argv[]) {
    FILE *myFile = getFile(argc, argv); // assume pointer is set to stdin
    int x = fgetc(myFile); // expected result
    int y = fgetc(myFile); // expected result
    int z = fgetc(myFile); // expected result

    int foo = bar(myFile); // unexpected result

    return 0;
}

int bar(FILE *myFile) {
    fseek(myFile, 4, 0);
    return fgetc(myFile);
}

2 ответов


Да, это совершенно нормально, что fseek не будет работать на stdin -- обычно он работает только с дисковым файлом или чем-то подобным.

хотя это действительно вещь POSIX, вы обычно можете использовать if (isatty(fileno(myFile))) чтобы получить, по крайней мере, довольно хорошее представление о том, будет ли поиск работать в определенном файле. В некоторых случаях isatty и/или fileno будет иметь ведущее подчеркивание (например, IIRC версии, поставляемые с компиляторами Microsoft).


Fseek () основан на lseek (), и страница lseek man обсуждает возможные ошибки, в том числе:

 [ESPIPE]           Fildes is associated with a pipe, socket, or FIFO.

Если stdin подключен к псевдо tty, я считаю, что он будет иметь поведение сокета.