C 言語で fscanf を使ってファイルを一行ずつ読む

胡金庫 2023年10月12日
  1. 関数 fscanf を使って C 言語でファイルを一行ずつ読み込む
  2. 関数 fscanf を用いて C 言語でファイルを一字一句読み取る
C 言語で fscanf を使ってファイルを一行ずつ読む

この記事では、C 言語で fscanf を使ってファイルを一行ずつ読み込む方法をいくつか説明します。

関数 fscanf を使って C 言語でファイルを一行ずつ読み込む

関数 fscanf は C 標準ライブラリのフォーマット付き入力ユーティリティの一部です。異なる入力ソースに対して複数の関数が提供されており、例えば stdin から読み込むための scanf や文字列から読み込むための sscanfFILE ポインタストリームから読み込むための fscanf などがあります。後者は通常のファイルを一行ずつ読み込んでバッファに格納するために用いることができます。

fscanfprintf と同様の書式指定を受け付けるが、その詳細はこのページ にあります。以下の例では、fopen 関数呼び出しを用いてサンプル入力ファイルを開き、ファイルサイズいっぱいのメモリを確保して読み込みストリームを格納しています。"%[^\n] " フォーマット文字列を指定して、改行文字が見つかるまでファイルストリームを読み込む。fscanf は入力が終了すると EOF を返すので、while ループを使って一行ずつ繰り返して出力します。

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

const char *filename = "input.txt";

int main(int argc, char *argv[]) {
  FILE *in_file = fopen(filename, "r");

  struct stat sb;
  stat(filename, &sb);

  char *file_contents = malloc(sb.st_size);

  while (fscanf(in_file, "%[^\n] ", file_contents) != EOF) {
    printf("> %s\n", file_contents);
  }

  fclose(in_file);
  exit(EXIT_SUCCESS);
}

出力:

> Temporary string to be written to file

前述のコードでは、入力ファイル名がファイルシステムに存在する場合は正常に実行される可能性が高いですが、複数回の関数呼び出しが失敗してプログラムが異常終了することがあることに注意してください。次のコード例は、エラーチェックルーチンを実装した修正版です。

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

const char *filename = "input.txt";

int main(int argc, char *argv[]) {
  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);

  while (fscanf(in_file, "%[^\n] ", file_contents) != EOF) {
    printf("> %s\n", file_contents);
  }

  fclose(in_file);
  exit(EXIT_SUCCESS);
}

出力:

> Temporary string to be written to file

関数 fscanf を用いて C 言語でファイルを一字一句読み取る

fscanf 関数を利用するもう一つの有用なケースは、ファイルを辿ってスペースで区切られたトークンをすべて解析することです。先ほどの例から変更すべき点は、フォーマット指定子を "%[^\n ] " に変更することだけであることに注意してください。システムコールの stat はファイルサイズを取得し、その値を malloc 引数に渡してバッファを確保します。この方法はシナリオによっては無駄かもしれませんが、最大の一行ファイルでもバッファに格納できることを保証します。

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

const char *filename = "input.txt";

int main(int argc, char *argv[]) {
  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);

  while (fscanf(in_file, "%[^\n ] ", file_contents) != EOF) {
    printf("> %s\n", file_contents);
  }

  fclose(in_file);
  exit(EXIT_SUCCESS);
}

出力:

> Temporary
> string
> to
> be
> written
> to
> file
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

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

LinkedIn Facebook

関連記事 - C File