12

コマンドライン引数に応じて、指定されたファイルまたは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);
}
4

3 に答える 3

14

はい、fseek動作しないのは完全に正常ですstdin。通常、ディスクファイル、またはかなり類似したものでのみ動作します。

これは実際にはPOSIXのことですが、通常はif (isatty(fileno(myFile)))、特定のファイルでシークが機能するかどうかについて、少なくともかなり良いアイデアを得るのに使用できます。場合によっては、isattyおよび/またはfileno先頭にアンダースコアが付きます(たとえば、Microsoftのコンパイラで提供されるバージョンのIIRCにはあります)。

于 2011-02-07T03:27:00.127 に答える
2

Fseek()はlseek()に基づいており、lseekのマニュアルページでは、次のようなエラーの可能性について説明しています。

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

stdinが疑似ttyに接続されている場合、ソケット動作があると思います。

于 2011-02-07T03:28:07.867 に答える
1

fseek機能に関するANSI規格の関連エントリは次のとおりです。

テキストストリームの場合、offsetはゼロであるか、offsetは、同じファイルに関連付けられたストリームでftell関数を以前に正常に呼び出したときに返される値であり、SEEK_SETである必要があります。

したがって、可能ですが、いくつかの制限があります

于 2019-03-31T22:23:52.643 に答える