<scanf関数>
(構文) scanf(書式文字列[,格納可変個引数]);
<書式文字列>
(例) scanf("%c", &c); //変数cに文字変換した入力データを格納
scanf("%x",
&n); //変数nに16進変換した入力データを格納
主なscanf関数の変換指定子には以下のようなものがあります。
変換指定子 |
意味 |
引数 |
c |
1文字として入力 |
文字型変数のアドレス |
d |
10進数で入力 |
int型変数のアドレス |
x |
16進数で入力 |
int型変数のアドレス |
o |
8進数で入力 |
int型変数のアドレス |
f |
float型変数に実数を入力 |
float型変数のアドレス |
s |
文字列を入力 |
文字型配列のアドレス |
*long型変数に対する入力の場合には,変換指定子の前に変換修飾子lを付加して%ldのように記述します。
*double型変数に対する入力の場合には,変換指定子の前に変換修飾子lを付加し,%lfのように記述します。printf関数とは異なる指定なので注意が必要です。
<変数にデータを入力する場合>
「&変数名」で変数のアドレスを指定します。
(例) int dt;
scanf("%d",
&dt);
&をわすれると,あらぬところにデータが書き込まれ危険です。
<配列にデータを入力する場合>
配列名だけでアドレスをあらわしているので,&をつける必要はありません。
(例) char str[256];
scanf("%s",
str); // &strではない
ただし,配列の各要素にデータを入力する場合には&配列名[添字]のように書く必要があります。
(例) char str[256];
scanf("%c",
&str[10]); // str[10]に1文字入力
<空白類文字は読み込めない>
scanf関数では半角スペース,タブ,改行などの空白類を区切り文字として使います。
(例) int i, j, k;
scanf("%d%d%d",
&i, &j, &k);
この例では,一つ入力するたびにEnterを押しても構いませんが、
10
20 30<enter>
のように空白を区切りにデータ入力をすることもできます。逆に空白を入力データに含めることはできません。
空白を含む文字列を読み込むときにはgets関数を用います。ただし,%c指定で文字を読み込むときに限り空白も入力できます。
<改行文字('\n')が残る>
scanf関数では,正しく入力しても最後の改行は入力バッファに残るため,2度目以降の入力に%c指定をした場合,おかしな動作になります。
一見問題なさそうな次の例も、文字が文字が入力できなくなります。
(例) scanf("%d", &a);
scanf("%c",
&c); // 入力できない
この問題を回避するには、いくつかの方法があります。
回避方法1:作業変数に'\n'をダミー入力する
scanf(...);
scanf("%c",&dummy);
//前に押された'\n'がはいる
scanf("%c",
&c); //本入力
回避方法2:getchar関数で読み捨てる
scanf(...);
(void)getchar(); //'\n'の読み捨て
scanf("%c",
&c); //本入力
回避方法3:代入抑制文字(*)を用いて,入力された'\n'を変数に代入しない
scanf(...);
scanf("%*c%c",
&c); //'\n'の代入阻止
回避方法4:" %c"で空白を読み飛ばす
scanf(...);
scanf("
%c", &c); //空白類文字の読み捨て
<書式文字列に変換指定以外を書く場合>
書式文字列に変換指定以外の文字を書くと,その文字まで正確に入力しなくてはならなくなります。
(例) scanf("input=%d", &n);
//「input=10<enter>」のように入力しなくてはならない.
scanf("%d\n",
&n);
// 空白文字以外を入力するまで空白類文字を読み捨て続ける.
// 数値の後にいくらEnterキーを押しても入力をやめられない.
scanf("%d,%d",
&n1, &n2);
// 「1,2<enter>」のようにカンマで区切った入力を要求