Using fseek with a file pointer that points to stdin

萝らか妹 提交于 2019-11-26 12:19:39

问题


Depending on command-line arguments, I\'m setting a file pointer to point either towards a specified file or stdin (for the purpose of piping). I then pass this pointer around to a number of different functions to read from the file. Here is the function for getting the file pointer:

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 found\\n\", argv[1]);
    }
    else
        myFile = stdin;
    return myFile;
}

When it\'s pointing to stdin, fseek does not seem to work. By that, I mean I use it and then use fgetc and I get unexpected results. Is this expected behavior, and if so, how do I move to different locations in the stream?

For example:

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);
}

回答1:


Yes, it's perfectly normal that fseek won't work on stdin -- it'll normally only work on a disk file, or something reasonably similar.

Though it's really a POSIX thing, you can typically use if (isatty(fileno(myFile))) to get at least a pretty good idea of whether seeking will work in a particular file. In some cases, isatty and/or fileno will have a leading underscore (e.g., IIRC the versions provided with Microsoft's compilers do).




回答2:


Fseek() is based on lseek(), and the lseek man page discusses possible errors, including:

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

If stdin is connected to a pseudo tty, I believe it will have socket behavior.




回答3:


Here is the relevant entry in the ANSI standard concerning the fseek function:

For a text stream, either offset shall be zero, or offset shall be a value returned by an earlier successful call to the ftell function on a stream associated with the same file and whence shall be SEEK_SET

So, possible but with some limitations



来源:https://stackoverflow.com/questions/4917801/using-fseek-with-a-file-pointer-that-points-to-stdin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!