使用带有指向stdin的文件指针的fseek

根据命令行参数,我设置一个文件指针指向指定的文件或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 found\n", 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); } 

是的, fseek无法在stdin上运行是完全正常的 – 它通常只能在磁盘文件上工作,或者类似的东西。

虽然它确实是一个POSIX的东西,你通常可以使用if (isatty(fileno(myFile)))来至少很好地了解搜索是否可以在特定文件中工作。 在某些情况下, isatty和/或fileno将具有前导下划线(例如,IIRC与Microsoft的编译器一起提供的版本)。

Fseek()基于lseek(),lseek手册页讨论了可能的错误,包括:

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

如果stdin连接到伪tty,我相信它会有套接字行为。