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.