feof()とferror()

fgetc() が EOF を返した場合、エラーが起こったのかファイルの終わりに達したのか判定できない。バイナリファイルを読み込んでいる途中で EOF と同じ値が返ってきた時もファイルの終わりなのか有効なデータなのか判定できない。
これらを判定するためには、feof() と ferror() を使う。一般的な形式は次のとおり。

int feof(FILE *ストリーム);
int ferror(FILE *ストリーム);

feof() はストリームの終わりに達していると 0 以外の値(真)を返し、そうではければ 0 (偽)を返す。
ferror() はエラーが起これば 0 以外の値を返し、そうでなければ 0 を返す。

FILE *fp;
.
.
.
while (!feof(fp)) {
    ch = fgetc(fp);
    if (ferror(fp)) {
        printf("File error!\n");
        break;
    }
}

上のコードでは、feof(fp) が偽のあいだ while でループし、ストリームからデータを読み込むたびに ferror(fp) でエラーチェックをしている。

次のプログラムはファイルのコピーを行う。その際、完全なエラー検査を行う。

#include
#include

int main(int argc, char *argv[])
{
    FILE *from, *to;
    char ch;

    if (argc != 3) {
        printf("Usage: %s \n", argv[0]);
        exit(1);
    }

    /* open src file */
    if ((from = fopen(argv[1], "rb")) == NULL) {
        printf("Cannot open src file.\n");
        exit(1);
    }

    /* open dest file */
    if ((to = fopen(argv[2], "wb")) == NULL) {
        printf("Cannot open dest file.\n");
        exit(1);
    }

    /* copy file */
    while (!feof(from)) {
        ch = fgetc(from);
        if (ferror(from)) {
            printf("Error: at reading file.\n");
            exit(1);
        }
        if (!feof(from)) {
            fputc(ch, to);
        }
        if (ferror(to)) {
            printf("Error: at writing to file.\n");
            exit(1);
        }
    }

    if (fclose(from) == EOF) {
        printf("Error: at closing src file.\n");
        exit(1);
    }

    if (fclose(to) == EOF) {
        printf("Error: at closing dest file.\n");
        exit(1);
    }

    return 0;
}

実行例:

takatoh@nightschool $ ./sample_9_3
Usage: ./sample_9_3  
takatoh@nightschool $ ./sample_9_3 myfile myfile2
takatoh@nightschool $ cat myfile2
This is a test for file system.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください