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.