1. scanf関数
キーボードから書式付きで入力します。
scanf() の f は “format”(書式) の f です。scanf() は printf() と同様に書式指定を行うことにより、「A」のキーを押しても、16進数で入力したり、文字で入力したりというように入力形式を変えることが出来ます。
【書き方】
scanf( 書式文字列, 格納可変個引数 );
(1) 書式文字列
“” で囲まれた文字列です。以下の変換指定だけを記述するのが一般的です。
変換指定文字列 | 意味 | 使われるデータ型 |
---|---|---|
%c | 1文字として入力する | 文字型 |
%d | 10進数で入力する | 整数型 |
%x | 16進数で入力する | |
%o | 8進数で入力する | |
%f | 浮動小数点数を入力する | 浮動小数点型 |
%s | 文字列を入力する | 文字型配列 |
(2) 格納可変個引数
入力データを格納する領域のアドレス(アドレスについてはポインタの章で詳しく説明します。)を指定します。
変数にキーボードからデータを入力
変数のアドレスを「&変数名」で記述します。
// 例
int dt;
scanf("%d", &dt);

文字型配列にキーボードから文字列を入力
配列の先頭要素のアドレスを「配列名」で記述します。「&」は不要です。
// 例
char st[100];
scanf("%99s", st); // 99文字以上は入力できない

scanf関数の使用例 サンプルプログラム
#include <stdio.h>
int main(void)
{
char c;
int i;
float f;
double d;
long l;
char st[80];
printf("1文字入力=");
scanf("%c",&c); // 文字読み込み '&'が必要
printf("1文字出力:%c\n",c);
printf("文字列入力=");
scanf("%79s",st); // 文字列読み込み '&'は不要
printf("文字列出力:%s\n",st);
printf("10進入力=");
scanf("%d",&i);
printf("10進出力:%d\n",i);
printf("16進入力=");
scanf("%x",&i);
printf("16進出力:%x\n",i);
printf("long入力=");
scanf("%ld",&l); // %ld でlong型入力を行う
printf("long出力:%ld\n",l);
printf("浮動小数点数入力=");
scanf("%f",&f);
printf("浮動小数点数出力:%f\n",f);
printf("double入力=");
scanf("%lf",&d); // %lf でdouble型入力を行う
printf("double出力:%16f\n",d);
return 0;
}
【実行結果例】
1文字入力=a
1文字出力:a
文字列入力=abcde
文字列出力:abcde
10進入力=11
10進出力:11
16進入力=2b
16進出力:2b
long入力=1234567890
long出力:1234567890
浮動小数点数入力=12.345
浮動小数点数出力:12.345000
double入力=123456789.123456
double出力:123456789.123456
※ 水色字はキーボードからの入力
2. scanf関数の注意事項
(1) 空白類(スペース、改行、タブなど)は読み込まない
scanf() の “%s” 変換では空白類がくると読み込みを終了します。そのため、
This is a pen.
といった文字列を読み込むことはできません。
この例では「This」だけが読み込まれます。 (空白類を含む文字列を読み込むときには fgets() を用います。fgets() については「標準入出力関数(2)」の章で説明します。)
(2) 改行文字が残る
キーボードから入力された文字はバッファと呼ばれる作業領域にいったん読み込まれ、エンターキーが入力されるとフラッシュ(バッファをクリアし、再びバッファリングが行える状態にすること)されます。
scanf() では、正しく入力しても最後の改行文字はバッファの中に残るため、おかしな動作になるときがあります。(scanf() 実行後に、scanf() の “%c” 変換を行ったとき)

【回避方法】
いくつか方法はありますが、一番簡単な回避方法は、
scanf(" %c", &c);
のように、%c の前に半角スペースを入れることです。このように記述すると、空白類文字を無視して次の文字を読み取ります。
(3) 読み込み不一致
変換指定文字列で、期待していなかったデータを入力すると、 バッファのデータをそのまま残し、動作を終了してしまいます。
// 例
int data;
scanf("%d", &data); // 10進数値以外は入力しない
〇 演習問題
問1
文字型配列 str[80] を宣言し、この str に好きな文字列をキーボードから入力しなさい。
入力したら、出力して内容を確認しなさい。
【実行結果例】
文字列の入力 = computer
入力文字列:computer
※ 水色字はキーボードからの入力
問2
- キーボードから入力した10進数を、10進数と16進数で出力して内容を確認しなさい。
- キーボードから入力した16進数を、10進数と16進数で出力して内容を確認しなさい。
- キーボードから入力した1文字を、文字と10進数、16進数で出力して内容を確認しなさい。
- キーボードから入力した long型整数を、出力して内容を確認しなさい。
- キーボードから入力した float型浮動小数点数を、出力して内容を確認しなさい。
- キーボードから入力した double型浮動小数点数を、出力して内容を確認しなさい。
【実行結果例】
10進入力 = 11
10進出力:11
16進出力:b
16進入力 = 2b
10進出力:43
16進出力:2b
1文字入力 = A
1文字出力:A
10進出力:65
16進出力:41
long入力 = 1234567890
long出力:1234567890
float入力 = 12.345
float出力:12.345000
double入力 = 123456789.123456
double出力:123456789.123456
※ 水色字はキーボードからの入力
解答例
// 問1
#include <stdio.h>
int main( void )
{
char str[80];
printf("文字列の入力 = ");
scanf( "%79s", str );
printf( "入力文字列:%s\n", str );
return 0;
}
// 問2
#include <stdio.h>
int main( void )
{
int a;
printf("10進入力 = ");
scanf("%d", &a);
printf("10進出力:%d\n", a);
printf("16進出力:%x\n", a);
printf("16進入力 = ");
scanf("%x", &a);
printf("10進出力:%d\n", a);
printf("16進出力:%x\n", a);
char c;
printf("1文字入力 = ");
scanf(" %c", &c);
printf("1文字出力:%c\n", c);
printf("10進出力:%d\n", c);
printf("16進出力:%x\n", c);
long l;
printf("long入力 = ");
scanf("%ld", &l);
printf("long出力:%ld\n", l);
float f;
printf("float入力 = ");
scanf("%f", &f);
printf("float出力:%f\n", f);
double d;
printf("double入力 = ");
scanf("%lf", &d);
printf("double出力:%f\n", d);
return 0;
}
● 補足:Visual C++でscanfを使用する場合
Microsoft の Visual Studio で使われている C言語 および C++言語 のコンパイラである Visual C++ では、scanf などの一部の標準関数に対して、セキュリティ上の理由から警告やエラーが出ることがあります。特に scanf は、入力サイズの制限がない場合にバッファオーバーフローを引き起こしやすいため、Visual C++では、より安全な scanf_s関数 の使用が推奨されています。
Visual C++で標準の scanf を使いたい場合は、次の前処理指令を追加することで、セキュリティ警告を無効にできます。
#define _CRT_SECURE_NO_WARNINGS
この文をプログラム先頭に追加すると、scanf のようなセキュリティ警告を出す関数の使用を許可します。
コメント