C言語入門講座。関数、サンプル集を参考にして、 C言語をマスターしよう。初心者から上級者まで。

ファイルの内容を書式に従い変換して入力する

2012.08.10

fscanf関数は、ファイルの内容を書式に従い変換(編集)して、引数で指定した領域に入力します。

#include <stdio.h>
int fscanf(FILE *stream, const char *format, …);

*streamはfopen関数で取得した、ファイルポインタを指定します。
*format(書式)は第3引数以降で指定する領域に入力する値の変換形式を指定します。
第3引数以降は可変引数で、任意の引数を指定できます。ただし、*formatにより、間接的に引数の型名と個数を指定することになります。fscanf関数がこれらの領域に入力した値を設定しますので、引数は参照渡し(call by reference)になります。

戻り値として、入力した要素の個数を返します。また、ファイルの終わりや、エラーの場合はEOFの値を返します。

*format(書式)は%(パーセント)記号で始まり、「代入抑止フラグ」、「最大フィールド幅」、「長さ指定子」、「変換指定子」が続きます。%と変換指定子以外は省略可能です。

代入抑止フラグは*(アスタリスク)記号で指定します。データは入力しますが、捨ててしまいます。第3引数以降に指定した変数に値を設定しませんので、引数(格納変数)を指定する必要は有りません。

最大フィールド幅は十進整数値で、入力する文字数の最大値を指定します。この値に達するか、一致しない文字が現れるまで読み込みます。ほとんどの変換では、先頭のホワイトスペース(スペースやタブ、等)やヌル文字(’\0’)は最大フィールド幅には含みません。

長さ指定子は数値を表す変換指定子に対して指定でき、次のような意味があります。

  • hはshort型を表します。
  • l(小文字のL)は整数への変換入力の場合は、long int型かunsigned long int型を表し、十進浮動少数点実数への変換入力の場合は、double型を表します。
  • Lは整数への変換入力の場合は、long long型を表し、十進浮動少数点実数への変換入力の場合は、long double型を表します。

変換指定子は変換の型を指定します。変換指定子には下表のようなものがあります。

変換指定子 型名 意味
c char 通常は1文字を入力します。ただし、最大フィールド幅を指定すれば、指定した分の文字を入力します。なお、入力ストリーム中のホワイトスペースは入力します。入力したく無い場合は、書式制御文字列中に明示的にスペースを指定します。
d int 符号つき十進整数として入力します。long型に入力する場合は、長さ指定子のl(小文字のL)を、long long型に入力する場合はLを付加します。
f float 符号つき浮動小数点実数値として入力します。double型に入力する場合は、長さ指定子のl(小文字のL)を、long double型に入力する場合はLを付加します。(e、E、gも同じです。)
i int 0x又は、0Xで始まる場合は十六進数、0で始まる場合は八進数、その他の場合は十進数値として入力します。
n int ここまでに入力された文字数を保存します。
o、u、x、X unsigned int 符号なし八進数(o)、符号なし十進数(u)、符号なし十六進数(xとX)として入力します。
p void * ポインタ値として入力します。
s char[] 文字列として入力します。入力した文字列の終端にはヌル文字(’\0’)が追加されます。なお、入力ストリーム中に、ホワイトスペースが現れるか、最大フィールド幅に達した場合は文字列の入力は停止します。
[文字列] char[] 「文字列」中の文字に一致した文字又は、不一致の文字を文字列として入力します。「文字列」の先頭に^(やま)記号を付けると、不一致を意味します。また、連続した文字の中の1文字は-(マイナス)記号で指定ができます。(例えば、英大文字ならば[A-Z]の様に指定できます。)

次の例題プログラムは肥満度(BMI)情報を格納したtemp_2.txtファイル(固定長テキストレコード形式)を入力して、肥満度情報を出力します。ちなみに、temp_2.txtファイルには番号(3文字の整数)、身長と体重及び、肥満度(各7文字の十進浮動少数点数で小数点以下2位まで)が格納されています。

プログラム 例

#include <stdio.h>

int main()
{
  FILE     *fp;
  int      number;         /* 番号 */
  double   weight;         /* 体重 */
  double   height;         /* 身長 */
  double   bmi;            /* 肥満度 */
  int      return_code = 0;

  if ((fp = fopen('temp_2.txt', 'r')) != NULL) {
    while(fscanf(fp, '%3d%7lf%7lf%7lf',
                 &number, &weight, &height, &bmi) != EOF) {
      printf('%03d番目\n', number);
      printf('\t体重:%.2fKg\n', weight);
      printf('\t身長:%.2fCm\n', height);
      printf('\t肥満度(BMI):%.2f\n', bmi);
    }

    fclose(fp);
  }
  else {
    printf('ファイルのオープンに失敗しました\n');
    return_code = 1;
  }

  return return_code;
}

例の実行結果

$ cat temp_2.txt
0010067.500175.500021.92
0020088.000187.800024.95
0030054.300164.000020.19
$
$ ./fscanf.exe
001番目
        体重:67.50Kg
        身長:175.50Cm
        肥満度(BMI):21.92
002番目
        体重:88.00Kg
        身長:187.80Cm
        肥満度(BMI):24.95
003番目
        体重:54.30Kg
        身長:164.00Cm
        肥満度(BMI):20.19
$

関連記事