2011-02-07 34 views
8

根据命令行参数,我将文件指针设置为指向指定文件或标准输入(用于管道)。然后我将这个指针传递给许多不同的函数来从文件中读取。这里是得到该文件指针的函数:将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; 
} 

当它指向标准输入,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); 
} 
+0

你的示例代码对我来说看起来很好。 (除非文件不存在,但这与您的问题无关) – 2011-02-07 03:14:23

+0

对我来说似乎是正确的。它是什么编译器?你可能会尝试在bar()函数内部打印指针(stdin和myFile)来检查它们是否相同。 – leonbloy 2011-02-07 03:21:49

+0

@leonbloy:我发现问题实际上是用`fseek()`。显然,当指针指向标准输入时它不工作?对此有何想法? (更新了问题) – 2011-02-07 03:23:27

回答

12

是的,这是完全正常的,fseek不会在stdin工作 - 它会通常只有一个磁盘文件的工作,或者说相当类似。

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

1

FSEEK()是基于lseek的()和lseek的手册页讨论可能出现的错误,包括:

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

如果标准输入连接到一个伪TTY,我相信这将有插座的行为。