導入
printf は画面に、scanf は標準入力から、書式(%d や %s)を指定して読み書きする関数でした。実は printf は「stdout(標準出力)という特別なファイルに書き込む fprintf」の省略形にすぎません。同じ考え方で、普通のファイルに対しても書式付きの読み書きができます。
説明
fprintf(fp, "書式", 値...)…printfと同じ書式指定子がそのまま使えます。書き込み先をファイルポインタfpで指定するだけの違いです。fscanf(fp, "書式", &変数...)…scanfと同じ書式指定子で、ファイルから読み込みます。
fscanf の戻り値は「正しく読み取れた項目の数」です。ファイルの終端に達すると、期待した項目数より少ない値(あるいは EOF)が返るので、while (fscanf(...) == 項目数) { ... } という形でファイルを最後まで読み進めるのが定番のパターンです。
#include <stdio.h>
int main(void) {
FILE *fp = fopen("/home/user/score.txt", "w");
if (fp == NULL) {
printf("書き込み用に開けませんでした\n");
return 1;
}
fprintf(fp, "%s %d\n", "Taro", 85);
fprintf(fp, "%s %d\n", "Hanako", 92);
fclose(fp);
printf("書き込み完了\n");
fp = fopen("/home/user/score.txt", "r");
if (fp == NULL) {
printf("読み込み用に開けませんでした\n");
return 1;
}
char name[32];
int score;
while (fscanf(fp, "%s %d", name, &score) == 2) {
printf("%sさんの得点は%dです\n", name, score);
}
fclose(fp);
return 0;
}
%s は空白(スペースや改行)で区切られた1つの単語を読み取り、char の配列に格納します。配列は & を付けずにそのまま渡すのがポイントです(配列名はすでに先頭アドレスを表すため)。一方、int などの変数は scanf のときと同様に &score のようにアドレスを渡します。
やってみよう
得点をもう1人分追記して、3行とも表示されることを確認しましょう。書式を %d(整数)から %f(小数)に変え、書き込む値も小数に変えると何が起こるか試してみてください。
演習
名前と年齢を1組、fprintf でファイルに書き込み、fscanf で読み込んで「〇〇さんは△△歳です」の形式で表示してください。
ヒント1を見る
fprintf(fp, "%s %d\n", "Yamada", 20); のように書き込みます。
ヒント2を見る
読み込みは char name[32]; int age; fscanf(fp, "%s %d", name, &age);。名前の配列には & を付けません。