Linux講座にようこそ。このページは「C言語プログラミング入門 - 第14章.ライブラリ関数 - 入出力ライブラリ」です。

C言語プログラミング入門

14. ライブラリ関数(5/36) - 入出力ライブラリ(4/10)

14.7 書式入力関数

ここで紹介する入力関数は文字列を入力しますが、入力した文字列を書式制御文字列に従い型変換して、直接int型やdoubl型などの変数に格納します。格納する変数は引数で指定しますので、関数側から引数で指定した領域に値を設定することになります。従って、引数の受け渡しは「参照渡し」になります。参照渡しについては「9. プログラムの部品化のための関数(2/3)」をご覧下さい。

14.7.1 fscanf関数

fscanf関数はファイルポインタに対応したファイルから入力た文字列を、書式制御文字列に従い型変換して、引数に指定した変数に設定します。

【表14-1-16】 fscanf関数
形式#include <stdio.h>
int fscanf(FILE *fp, const char *format, ...);
返り値入力できた場合は入力したデータの数を返します。ファイルの終端やエラーを検出した場合はEOFを返します。また、入力したデータが型変換できない場合(英字をint型に変換、等)は、その時点で入力を終了します。
引数
FILE *fp
入力するファイルのファイルポインタを指定します。
const char *format
書式制御文字列を指定します。
...
入力したデータを格納する変数を指定します。参照渡しになりますので変数のアドレス(ポインタ)を指定します。
使用法、
返り値がEOF以外の場合は入力出来ましたが、期待したデータが全て入力できたかどうかは返り値をチェックする必要が有ります。

第2引数のformat(書式制御文字列)は「%(パーセント)」で始まり、「代入抑止フラグ」、「最大文字幅」、「サイズ指定子」、「変換指定子」が続きます。%と変換指定子以外は省略可能です。なお、これら以外の文字を指定した場合は、入力ストリーム中に一致した文字が現れると、それをスキップします。

代入抑止フラグ
*(アステリスク)で指定します。データは入力しますが捨ててしまいます。第3引数以降に指定した変数に値を設定しませんので、引数(格納変数)を指定する必要は有りません。
最大文字幅
文字列入力の場合の最大入力文字数を指定します。最大文字幅より長い文字列を入力しても最大文字幅以降のデータは読み飛ばされます。
サイズ指定子
short型を表す「h」、longやdoubleを表す「l」(小文字のL)及び、long double型を表す「L」を指定できます。これらは数値データを入力したい場合に指定できます。
変換指定子
入力したデータを、どのような型に変換するかを「【表14-1-17】 変換指定子一覧」に示す変換指定子で指定します。数値に変換する場合にはサイズ指定子と組み合わせることができます。
【表14-1-17】 変換指定子一覧
変換指定子説明
dint十進整数値に変換します。
iint0xまたは、0Xで始まる場合は十六進数、0で始まる場合は八進数、その他の場合は十進数値として変換します。
ounsigned int八進数値に変換します。
uunsigned int十進数値に変換します。
xまたは、Xunsigned int十六進数値に変換します。
ffloat浮動小数点数に変換します。(e、E、gも同じです)
schar型の配列文字列に変換します。終端にはヌル文字('\0')が追加されます。なお、入力ストリーム中に、空白(スペースやタブ)が現れるか、最大文字幅に達した場合は文字列の入力は終了します。
cchar通常は1文字に変換します。ただし、最大文字幅を指定すれば指定した分の文字に変換します。なお、入力ストリーム中の空白は入力します。入力したくない場合は、書式制御文字列中に明示的にスペースを指定します。
[文字列]char型の配列[文字列]中の文字に一致した文字または、不一致の文字を入力します。[文字列]の先頭に^(アクサンシルコンフレックス)を付けると、不一致を意味します。また、連続した文字の中の1文字は-(負記号)で指定ができます。(例えば、英大文字ならば[A-Z]の様に指定できます)
pvoidへのポインタポインタ値に変換します。
nintここまでに入力された文字数を取得します。

浮動小数点数の入力は、float型として入力する場合の書式は「%f」ですが、double型として入力する場合は、サイズ指定子の「l」を付加して「%lf」になりますので注意して下さい。

14.7.2 scanf関数

scanf関数は標準入力から入力した文字列を書式制御文字列に従い型変換して、引数に指定した変数に設定します。fscanf関数との相違は入力が標準入力に限定されていることだけです。

【表14-1-18】 scanf関数
形式#include <stdio.h>
int scanf(const char *format, ...);
返り値fscanf関数と同じです。
引数
const char *format
書式制御文字列を指定します。内容はfscanf関数と同じです。
...
入力したデータを格納する変数を指定します。参照渡しになりますので変数のアドレス(ポインタ)を指定します。

14.7.3 sscanf関数

sscanf関数は文字列を書式制御文字列に従い型変換して、引数に指定した変数に設定します。fscanf関数との相違は入力がファイルではないことだけです。

【表14-1-19】 sscanf関数
形式#include <stdio.h>
int sscanf(const char *str, const char *format, ...);
返り値fscanf関数と同じです。
引数
const char *str
変換する文字列を指定します。
const char *format
書式制御文字列を指定します。内容はfscanf関数と同じです。
...
変換したしたデータを格納する変数を指定します。参照渡しになりますので変数のアドレス(ポインタ)を指定します。

14.7.4 例題

下記のような,(コンマ)で区切って、番号・体重・身長・血液型のデータが登録されているex14_1_6.datファイルを入力して標準出力に出力します。ただし、血液型は出力しませんのでスキップします。

1,67,188,A
2,98,176.5,O
3,43.2,156.5,AB
4,55.5,167.5,B
5,75.7,166.5,A
  1. #include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5.     FILE        *fp;
  6.     char        in_file[] = "./DATA/ex14_1_6.dat";
  7.     short int   number;            /* 番号  */
  8.     float       weight;            /* 体重  */
  9.     double      height;            /* 身長  */
  10.     int         return_code = 0;
  11.  
  12.     if((fp = fopen(in_file, "r")) != NULL)
  13.     {
  14.         printf("番号\t体重\t身長\n");
  15.         /*  番号、体重、身長を入力 */
  16.         while(fscanf(fp, "%hd,%f,%lf,%*s",
  17.             &number, &weight, &height) != EOF)
  18.         {
  19.             printf("%d\t%.2f\t%.2f\n",
  20.                     number, weight, height);
  21.         }
  22.         fclose(fp);
  23.     }
  24.     else
  25.     {
  26.         printf("%sがオープン出来ませんでした。", in_file);
  27.         return_code = 1;
  28.     }
  29.  
  30.     return return_code;
  31. }
$ ./ex14_1_6.prg
番号    体重    身長
1       67.00   188.00
2       98.00   176.50
3       43.20   156.50
4       55.50   167.50
5       75.70   166.50
16行目
fscanf関数で番号・体重・身長データを入力します。番号を入力する変数numberはshort int型ですので、書式制御文字列はサイズ指定子の「h」を付加して「%hd」です。体重を入力する変数weightはfloat型ですので、書式制御文字列は「%f」です。身長を入力する変数heightはdouble型ですので、書式制御文字列はサイズ指定子の「l」を付加して「%lf」です。また、血液型は入力しませんので、書式制御文字列は「%*s」(文字列をスキップ)を指定しますが、入力する変数は指定しません。各項目の区切りはコンマですので、書式制御文字列中にコンマを含めます。
19行目
printf関数で入力したデータを出力します。fscanf関数の書式制御文字列と多少異なります。