2011-02-07 58 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,我相信這將有插座的行爲。