Thinkers'Studio
JavaとC言語の自習ツール
fgets と sscanf でファイルから入力するには

行単位のファイル入力には fgets関数

 ファイルから行単位で入力したいときは、fgets関数を使います。
 fgets は、行の最後にある改行も含めて読み込みます。 入力の最大サイズを指定するので、用意した領域を超えずに読み込むことができ、安全です。 行単位でファイルから読み、その内容に応じて処理を分けるなどの時に便利です。
 今回の Tips は、fgetssscanf を組み合わせて使う例です。

【 データファイルの例 】
 // で始まる行はコメント、その下のデータ行には最高気温と最低気温のデータが入っているものとします。
//file name : data.txt
//area : Kobe
//term : 2013/07/01-2013/07/04

//気温データ(max min)
29.6 22.2
30.1 26.8
28.3 21.8
28.3 25.1

fgetssscanf でファイル入力するプログラム例 】
 コメント行と空行を読み飛ばし、データ行から最高・最低気温を変数に入力してそれらの値と差を表示するプログラムです。
 fgets には、sizeof演算子を使って文字配列buf のサイズを渡しています。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main()
{
    FILE    *fp;
    char    buf[256];
    double  max, min;

    if( (fp = fopen( "data.txt", "r" )) == NULL ) {
        printf( "入力ファイルがオープンできません\n" );
        exit(1);
    }
    while( fgets( buf, sizeof(buf), fp ) ) {
        if( strncmp(buf,"//",2) == 0 || strcmp(buf,"\n") == 0 ) continue;
        if( sscanf( buf, "%lf %lf", &max, &min ) != 2 ) {
            printf( "データ書式が正しくありません\n" );
            break;
        }
        printf( "最高 %.1f, 最低 %.1f(差 %.1f)\n", max, min, max-min );
    }
    fclose( fp );
}
実行結果
最高 29.6, 最低 22.2(差 7.4)
最高 30.1, 最低 26.8(差 3.3)
最高 28.3, 最低 21.8(差 6.5)
最高 28.3, 最低 25.1(差 3.2)

fgets の最大入力サイズ

 fgets は行単位で読み込むといいましたが、ファイルの行が指定した最大入力サイズを超えるときは、一度の呼び出しで1行全部が読めるわけではありません。 たとえば、最大サイズを 8 にすると
while( fgets( buf, 8, fp ) ) {
      :
}
 ファイルの次の行は、何度かに分けて読み込まれます。
//file name : data.txt

 最初の呼び出しで「//file 」の7文字まで、次はその後ろの「name: 」の7文字、それ以降も7文字ずつ返され、最後は「t(と改行)」です。 計4回の fgets呼び出しでこの1行が読み込まれます (最大サイズ8を指定したのに7文字までしか読まれないのは、fgets が最後に '\0' をつけるので、その分です)。

(今回のクイズです)
 上と同様に最大入力サイズが 8 のとき、次のファイルの内容は全部で何回の fgets呼び出しで入力できるでしょうか?
         (1行目) 改行だけの行
1234567  (2行目) ピタリと7文字?
a    b   (3行目) 間に4つの空白がある
   (答えは、次回のC言語の Tips で ・・・)

[ 関連記事 ] fscanf で csvファイルから入力, 入力時に不要データをスキップ

前回のクイズは自習でした: (前回の問題を見る