web-dev-qa-db-ja.com

fgets()の戻り値

最近、CI/Oでの作業を開始しました。これが私の質問です-
ファイルがあり、そこから入力を読み取りました。次に、fgets()を使用して、何らかの方法で使用するバッファー内の文字列を取得します。ここで、入力がバッファに対して短すぎる場合、つまりfgets()による最初の読み取りがEOFに達した場合はどうなりますか。 fgets()NULLを返す必要がありますか(fgets()のドキュメントを読んだので)?それはそうではないようで、私は適切に私の入力を受け取ります。その上、私のfeof(input)EOFに達したとは言いません。
これが私のコードスニペットです。

char    buf[BUFSIZ];
FILE    *input,
        *output;

input   = fopen(argv[--argc], "r");
output  = fopen(argv[--argc], "w");

/**
 *  If either of the input or output were unable to be opened
 *          we exit
 */
if (input == NULL) {
    fprintf(stdout, "Failed to open file - %s.\n", argv[argc + 1]);
    exit(EXIT_FAILURE);
}

if (output == NULL) {
    fprintf(stdout, "Failed to open file - %s.\n", argv[argc + 0]);
    exit(EXIT_FAILURE);
}

if (fgets(buf, sizeof(buf), input) != NULL) {
    ....
}

/**
 *  After the fgets() condition exits it is because, either -
 *      1) The EOF was reached.
 *      2) There is a read error.
 */
if (feof(input)) {
    fprintf(stdout, "Reached EOF.\n");
}
else if (ferror(input)) {
    fprintf(stdout, "Error while reading the file.\n");
}
11
yadav_vi

fgets()のドキュメントには、あなたが考えていることは書かれていません。

私のマンページから

fgets()は、ストリームから最大でsize文字未満の文字を読み取り、sが指すバッファーに格納します。 EOFまたは改行の後に読み取りが停止します。改行が読み込まれると、バッファに格納されます。終端のnullバイト( '_\0_')は、バッファの最後の文字の後に格納されます。

以降

gets()およびfgets()は、成功した場合はsを返し、エラーの場合、または文字が読み込まれていないときにファイルの終わりが発生した場合はNULLを返します。

EOFはエラー条件として扱われ、NULLを返すと言っているのではありません。実際、NULLが発生するのは、no文字が読み取られたときにEOFが発生する場合のみです。

POSIX標準(アクセシビリティの低いC標準に従う)は次のとおりです http://pubs.opengroup.org/onlinepubs/009695399/functions/fgets.html および

正常に完了すると、fgets()sを返します。ストリームがファイルの終わりにある場合、ストリームのファイルの終わりインジケーターが設定され、fgets()はnullポインターを返します。読み取りエラーが発生した場合、ストリームのエラーインジケーターが設定され、fgets()はnullポインターを返し、errnoを設定してエラーを示します。

これは、呼び出されたときに実際にNULLにある場合、つまりanyバイトの場合にのみ、EOFを返すことを明確に示しています。読み取られても、NULLは返されません。

15
abligh