C 言語で feof 関数を使用する

胡金庫 2023年10月12日
  1. 関数 feof を使って C 言語でファイルストリームのファイル終端インジケータをチェックする
  2. 関数 feofferror を使って C 言語でファイルストリームの有効な位置をテストする
C 言語で feof 関数を使用する

この記事では、C 言語で feof 関数を使用する方法をいくつか説明します。

関数 feof を使って C 言語でファイルストリームのファイル終端インジケータをチェックする

関数 feof は C 標準入出力ライブラリの一部であり、<stdio.h> ヘッダで定義されています。関数 feof は与えられたファイルストリームのファイル終端インジケータを調べ、EOF がセットされていれば 0 以外の整数を返します。これは、FILE ポインタを唯一の引数として受け取ります。

この関数は feof がゼロを返すまで呼び出され、ファイルストリームが EOF に達していないことを意味します。関数 getline の戻り値を条件文で確認し、成功した場合にのみ printf を呼び出して読み込んだ行を出力することに注意してください。

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

const char* filename = "input.txt";

int main(void) {
  FILE* in_file = fopen(filename, "r");
  if (!in_file) {
    perror("fopen");
    exit(EXIT_FAILURE);
  }

  struct stat sb;
  if (stat(filename, &sb) == -1) {
    perror("stat");
    exit(EXIT_FAILURE);
  }

  char* contents = NULL;
  size_t len = 0;

  while (!feof(in_file)) {
    if (getline(&contents, &len, in_file) != -1) {
      printf("%s", contents);
    }
  }

  fclose(in_file);
  exit(EXIT_SUCCESS);
}

関数 feofferror を使って C 言語でファイルストリームの有効な位置をテストする

あるいは、ファイルの内容を読み込む前にファイルストリームの位置をテストするために feof を利用することもできます。この場合、stat 関数呼び出しで取得したファイルのサイズを取得する fread 呼び出しを用いてファイルを読み込むことになります。読み込んだバイトを格納するバッファは、malloc 関数を用いてヒープ上に確保されていることに注目してほしい。また、EOF インジケータとともにファイルストリームの error 状態をテストするために、条件文の中に ferror 関数を含めた。

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

const char* filename = "input.txt";

int main(void) {
  FILE* in_file = fopen(filename, "r");
  if (!in_file) {
    perror("fopen");
    exit(EXIT_FAILURE);
  }

  struct stat sb;
  if (stat(filename, &sb) == -1) {
    perror("stat");
    exit(EXIT_FAILURE);
  }

  char* file_contents = malloc(sb.st_size);
  if (!feof(in_file) && !ferror(in_file))
    fread(file_contents, 1, sb.st_size, in_file);
  printf("read data: %s\n", file_contents);

  free(file_contents);

  fclose(in_file);
  exit(EXIT_SUCCESS);
}

また、ferror は I/O ライブラリの一部であり、FILE ポインタオブジェクト上で呼び出すことができます。エラービットがファイルストリームに設定されている場合は、0 以外のインジケータを返します。3つの例はすべて、変数 filename で指定されたファイルの内容を出力することに注意してください。前のサンプルコードでは、printf 関数を用いて保存された内容を出力したが、よりエラーが発生しやすい方法は fwrite コールです。

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

const char* filename = "input.txt";

int main(void) {
  FILE* in_file = fopen(filename, "r");
  if (!in_file) {
    perror("fopen");
    exit(EXIT_FAILURE);
  }

  struct stat sb;
  if (stat(filename, &sb) == -1) {
    perror("stat");
    exit(EXIT_FAILURE);
  }

  char* file_contents = malloc(sb.st_size);
  if (!feof(in_file) && !ferror(in_file))
    fread(file_contents, 1, sb.st_size, in_file);
  fwrite(file_contents, 1, sb.st_size, stdout);

  free(file_contents);

  fclose(in_file);
  exit(EXIT_SUCCESS);
}
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C IO