C言語の基本|scanfで整数を入力する

キーボードから受け取った数字で、プログラムとのやり取りを始めよう。

これまで作成してきたプログラムでは、表示する数値や文章をソースコードの中にあらかじめ書いていました。

たとえば、次のprintfでは、表示される回数が5回に固定されています。

printf("今日は%d回ストレッチします。\n", 5);

このプログラムを実行すると、いつでも5回と表示されます。回数を10回に変更したければ、ソースコードを書き換えて、もう一度コンパイルしなければなりません。

しかし、実際のプログラムでは、実行する人が入力した値を使いたい場面がたくさんあります。

そこで使用するのがscanfです。

scanfを使うと、プログラムの実行中にキーボードから整数を入力し、その値を変数へ保存できます。保存した値は、計算に使ったり、printfで表示したりできます。

この部分では、次の内容を身につけることを目標にします。

  • scanfで整数を入力する
  • 入力された値を変数へ保存する
  • 変数に保存された値をprintfで表示する
  • 複数の整数を順番に入力する
  • scanfで起こりやすい書き間違いを確認する
  • 入力待ちになったときの操作を理解する

scanfの書き方では、変数名の前に&を付けます。初めて見ると少し難しく感じるかもしれませんが、最初から&の仕組みをすべて理解する必要はありません。

今は、scanfでint型の変数に整数を入れるときは、変数名の前に&を付けると覚えておきましょう。

scanfを使うと実行中に数値を決められる

printfだけを使用するプログラムでは、表示する数値をソースコード側で決めていました。

printf("今日は%d分歩きます。\n", 20);

この場合、20という数値は固定されています。

一方、scanfを使うプログラムでは、実行する人が歩く時間を入力できます。

たとえば、20と入力すれば20分と表示され、45と入力すれば45分と表示されます。ソースコードを書き換えなくても、入力によって表示内容を変えられるのです。

違いを整理すると、次のようになります。

方法数値を決める人数値を決めるタイミング
数値を直接printfに書くプログラムを作る人ソースコードの作成時
scanfで数値を受け取るプログラムを実行する人プログラムの実行中

scanfを使えるようになると、プログラムは決められた内容を一方的に表示するだけではなく、利用者から受け取った情報に応じて動けるようになります。

scanfを使ったプログラムの基本的な流れ

整数を入力して表示するプログラムは、次の順序で動きます。

手順処理内容
1int型の変数を用意する
2scanfで整数を受け取る
3入力された整数を変数へ保存する
4printfに変数を渡して値を表示する

scanfは、入力された整数を受け取る役割を持っています。ただし、scanfが値を受け取るためには、その値を保存する変数が必要です。

図1:scanfで入力した整数が表示されるまで

この図から分かること

キーボードから入力した整数は、scanfによって直接printfへ渡されるわけではありません。

入力された値は、いったんint型の変数へ保存されます。その後、printfが変数の値を取り出し、%dの位置に表示します。

つまり、次の流れを一つのまとまりとして理解することが大切です。

  • scanfは値を入力する
  • 変数は値を保存する
  • printfは保存された値を表示する

整数を3つ入力して健康計画を表示してみよう

最初のプログラムでは、次の3つの整数を入力します。

  • ウォーキングの時間
  • ストレッチの回数
  • 水を飲む回数

入力された整数は、それぞれ別の変数へ保存します。

入力した内容から健康計画を表示するプログラム

ファイル名:3_7_1.c

// キー入力した整数から健康計画を表示するプログラム
#include <stdio.h>

int main(void)
{
    int walk_minutes;    // ウォーキングをする時間
    int stretch_count;   // ストレッチをする回数
    int water_count;     // 水を飲む回数

    scanf("%d%d%d", &walk_minutes, &stretch_count, &water_count);

    printf("今日の健康計画を表示します。\n");
    printf("ウォーキングを%d分行います。\n", walk_minutes);
    printf("ストレッチを%d回行います。\n", stretch_count);
    printf("水を%d回飲みます。\n", water_count);

    return 0;
}
実行結果の例

プログラムを実行すると、scanfが整数の入力を待ちます。次のように、3つの整数を半角スペースで区切って入力し、Enterを押します。

入力例:

25 6 4

実行結果の例:

25 6 4
今日の健康計画を表示します。
ウォーキングを25分行います。
ストレッチを6回行います。
水を4回飲みます。

先頭の25 6 4は、キーボードから入力した内容です。その後に表示される文章では、それぞれの値が対応する位置に反映されています。

プログラムの内容を詳しく確認しよう

stdio.hを読み込む

#include <stdio.h>

scanfとprintfを使うために、stdio.hを読み込んでいます。

stdioはstandard input/outputを表しており、標準入力や標準出力に関係する機能が宣言されています。

今回のプログラムでは、次の機能を使用します。

関数役割
scanfキーボードから値を入力する
printf画面へ文章や数値を表示する

入力した整数を保存する変数を用意する

int walk_minutes;
int stretch_count;
int water_count;

scanfで受け取った値を保存するため、3つのint型変数を宣言しています。

変数名保存する内容入力例
walk_minutesウォーキングを行う時間25
stretch_countストレッチを行う回数6
water_count水を飲む回数4

intは整数を扱うための型です。

今回は3つの整数を別々に保存するため、変数も3つ用意しています。どのような値を保存する変数なのかが分かるように、それぞれ役割に合った名前を付けています。

scanfで3つの整数を受け取る

scanf("%d%d%d", &walk_minutes, &stretch_count, &water_count);

この1行が、キーボードから3つの整数を受け取る処理です。

それぞれの部分には、次の役割があります。

部分意味
scanfキーボードから値を読み取る関数
%d%d%d整数を3つ読み取る指定
&walk_minutes1つ目の整数を保存する場所
&stretch_count2つ目の整数を保存する場所
&water_count3つ目の整数を保存する場所

%dは、10進数の整数を読み取るための変換指定です。

今回は%dが3つ並んでいるため、scanfは3つの整数を順番に読み取ります。

入力した整数と変数の対応は、次のようになります。

25 6 4
入力順入力した整数保存される変数
1つ目25walk_minutes
2つ目6stretch_count
3つ目4water_count

scanfでは、%dの並び順と、その後に書いた変数の並び順が対応します。

scanfでは変数名の前に&を付ける

scanfの書き方で特に重要なのが、変数名の前に付いている&です。

&walk_minutes

&は、scanfに値の保存場所を伝えるために必要です。

&の詳しい仕組みは、アドレスやポインタを学習すると理解できるようになります。今の段階では、scanfでint型の変数に整数を入力するときの基本的な決まりとして覚えておけば大丈夫です。

printfでは変数名の前に&を付けません。

printf("%d\n", walk_minutes);

scanfとprintfの違いを整理すると、次のようになります。

使用する関数変数の書き方目的
scanf&walk_minutes変数へ値を入れる
printfwalk_minutes変数の値を表示する

同じ変数を使っていても、scanfでは&を付け、printfでは&を付けない点に注意しましょう。

図2:3つの入力と変数の対応関係

この図から分かること

scanfは、入力された整数を左から順番に読み取ります。

1つ目の25はwalk_minutes、2つ目の6はstretch_count、3つ目の4はwater_countへ保存されます。

このとき、次の3つを一致させることが重要です。

  • %dの数
  • &を付けて並べる変数の数
  • 実際に入力する整数の数

入力順を間違えると、値は別の変数へ保存されます。たとえば6 25 4と入力すれば、walk_minutesには6、stretch_countには25が入ります。

printfで入力された整数を表示する

scanfによって保存された値は、printfの%dで表示できます。

printf("ウォーキングを%d分行います。\n", walk_minutes);
printf("ストレッチを%d回行います。\n", stretch_count);
printf("水を%d回飲みます。\n", water_count);

ここでの%dの使い方は、整数を直接表示するときと同じです。

違うのは、printfへ渡している値です。

書き方表示する値
printf("%d分\n", 25);ソースコードに直接書いた25
printf("%d分\n", walk_minutes);walk_minutesに保存されている値

次の書き方では、常に25が表示されます。

printf("%d分\n", 25);

一方、次の書き方では、scanfでwalk_minutesへ保存された値が表示されます。

printf("%d分\n", walk_minutes);

このように変数を使うことで、入力内容に合わせて結果を変えられます。

スペースでもEnterでも入力を区切れる

次のscanfは、3つの整数を必要とします。

scanf("%d%d%d", &walk_minutes, &stretch_count, &water_count);

整数の区切りには、半角スペースや改行を使用できます。

3つの整数を1行で入力する場合は、次のようにします。

25 6 4

1つずつEnterを押して入力することもできます。

25
6
4

どちらの方法でも、入力順が同じなら保存される値も同じです。

初心者のうちは、必要な整数を確認しやすい半角スペース区切りがおすすめです。

入力待ちを停止と勘違いしないようにしよう

scanfを実行すると、必要な入力がそろうまでプログラムは次の処理へ進みません。

今回の最初のプログラムでは、scanfより前にprintfがありません。

scanf("%d%d%d", &walk_minutes, &stretch_count, &water_count);

そのため、実行直後は何も案内が表示されず、カーソルだけが点滅します。

この状態は、プログラムが停止しているのではなく、整数の入力を待っている状態です。

動かなくなったように見えたときは、次の点を確認しましょう。

  • 画面上でカーソルが点滅しているか
  • scanfが必要としている数の整数を入力したか
  • 入力した後にEnterを押したか
  • 整数以外の文字を入力していないか

scanfが3つの整数を必要としているときに、25と6だけを入力した場合は、3つ目の整数がまだそろっていません。そのため、プログラムは入力を待ち続けます。

入力前に案内を表示すると分かりやすい

入力待ちであることを伝えるには、scanfの前にprintfを置きます。

printf("歩く時間、ストレッチ回数、水を飲む回数を入力してください。\n");
scanf("%d%d%d", &walk_minutes, &stretch_count, &water_count);

このようにすると、プログラムを実行した人が何を入力すればよいのか分かりやすくなります。

特に複数の値を入力するプログラムでは、次の情報を案内すると親切です。

  • 入力する値の種類
  • 入力する順番
  • 単位
  • 入力する値の個数

案内メッセージを付けたプログラム

2つ目のプログラムでは、scanfの前に入力案内を表示します。入力する整数や順番が画面に表示されるため、操作しやすくなります。

入力案内を表示してから健康計画を受け取るプログラム

ファイル名:3_7_2.c

// 入力案内を表示して健康計画を受け取るプログラム
#include <stdio.h>

int main(void)
{
    int walk_minutes;    // ウォーキングをする時間
    int stretch_count;   // ストレッチをする回数
    int water_count;     // 水を飲む回数

    printf("歩く時間、ストレッチ回数、水を飲む回数を入力してください。\n");
    printf("3つの整数をこの順番で入力します。\n");

    scanf("%d%d%d", &walk_minutes, &stretch_count, &water_count);

    printf("今日の健康計画を表示します。\n");
    printf("ウォーキングを%d分行います。\n", walk_minutes);
    printf("ストレッチを%d回行います。\n", stretch_count);
    printf("水を%d回飲みます。\n", water_count);

    return 0;
}
実行結果の例

入力例:

30 8 5

実行結果の例:

歩く時間、ストレッチ回数、水を飲む回数を入力してください。
3つの整数をこの順番で入力します。
30 8 5
今日の健康計画を表示します。
ウォーキングを30分行います。
ストレッチを8回行います。
水を5回飲みます。

最初のプログラムとの違いは、scanfの前に2つのprintfが追加されていることです。

変数の宣言、scanfによる入力、printfによる結果表示という基本的な処理は変わっていません。

入力案内を表示する

printf("歩く時間、ストレッチ回数、水を飲む回数を入力してください。\n");
printf("3つの整数をこの順番で入力します。\n");

この2行が、入力する内容と順番を説明しています。

入力された値を変数へ保存する

scanf("%d%d%d", &walk_minutes, &stretch_count, &water_count);

入力された30、8、5は、左から順番に対応する変数へ保存されます。

30 → walk_minutes
8  → stretch_count
5  → water_count

保存された値を結果として表示する

printf("ウォーキングを%d分行います。\n", walk_minutes);
printf("ストレッチを%d回行います。\n", stretch_count);
printf("水を%d回飲みます。\n", water_count);

各変数の値が、それぞれの%dへ渡されます。

入力案内を追加しても、scanfとprintfの基本的な関係は同じです。

scanfで起こりやすい書き間違い

scanfを初めて使うときは、いくつかの部分で間違えやすくなります。特に注意したいのは、&、%dの数、入力する値の種類です。

変数名の前に&を付け忘れる

次の書き方では、変数名の前に&がありません。

scanf("%d%d%d", walk_minutes, stretch_count, water_count);

int型の変数へ整数を入力するときは、次のように&を付けます。

scanf("%d%d%d", &walk_minutes, &stretch_count, &water_count);

scanfの行を書いたら、各変数の前に&があるか確認しましょう。

%dと変数の数が一致していない

次の書き方では、%dが2つなのに、変数が3つ並んでいます。

scanf("%d%d", &walk_minutes, &stretch_count, &water_count);

正しく3つの整数を読み取るには、%dも3つ必要です。

scanf("%d%d%d", &walk_minutes, &stretch_count, &water_count);

基本となる対応関係は次のとおりです。

確認する項目今回必要な数
%d3個
&を付けた変数3個
入力する整数3個

この3つの数を一致させましょう。

整数を入力する場所に文字を入力する

%dは整数を読み取る指定です。

そのため、次のように英字を入力すると、期待した結果になりません。

thirty 8 5

1つ目の入力が整数ではないため、scanfはwalk_minutesへ値を正しく保存できません。

練習では、次のように半角の整数を入力しましょう。

30 8 5

必要な数より少ない整数しか入力していない

scanfに%dが3つある場合は、3つの整数が必要です。

次のように2つだけ入力してEnterを押すと、scanfは3つ目の入力を待ちます。

30 8

続けて5を入力し、Enterを押せば処理が進みます。

5

入力待ちが続いた場合は、%dの数を確認してみましょう。

入力順を間違える

次の順番で入力するように案内されているとします。

歩く時間 ストレッチ回数 水を飲む回数

ここで5 30 8と入力すると、変数には次のように保存されます。

変数保存される値
walk_minutes5
stretch_count30
water_count8

scanfは、数値の意味を自動的に判断して並べ替えることはありません。入力された順番どおりに値を保存します。

図3:scanfを正しく使うための確認ポイント

この図から分かること

scanfで整数を入力するときは、コードと操作の両方を確認する必要があります。

コードでは、%dの数と変数の数をそろえ、int型の変数名の前に&を付けます。操作では、必要な数の整数を正しい順番で入力します。

動作がおかしいと感じたら、次の順番で確認すると原因を見つけやすくなります。

  1. %dはいくつあるか
  2. 変数の数は%dと同じか
  3. 各変数の前に&が付いているか
  4. 必要な数の整数を入力したか
  5. 入力順は案内どおりか
  6. 整数以外の文字を入力していないか

GCCとVisual C++でのscanfの扱い

scanfは、C言語の標準ライブラリに用意されている関数です。ただし、使用する開発環境によって、コンパイル時の表示が異なることがあります。

開発環境scanfの扱い
GCC標準のscanfを使用できる
Visual C++scanfに警告が表示されることがある

Visual C++では、安全性を重視する独自の方針によって、scanfに警告が表示されることがあります。

これは、C言語の規格からscanfが削除されているという意味ではありません。Visual C++側が、より安全性を意識した関数の利用をすすめているためです。

この教材で使用しているGCCでは、次のように標準のscanfを使って学習を進められます。

scanf("%d", &walk_minutes);

Visual C++で標準のscanfを使用するときは、ソースファイルの先頭で次のマクロを定義し、警告を抑える方法もあります。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

ただし、GCCを使って学習している段階では、この設定を追加する必要はありません。まずは標準的なscanfの書き方を身につけましょう。

今の段階で覚えておきたいこと

scanfを学び始めた段階では、内部の仕組みをすべて理解しようとしなくても大丈夫です。まずは、入力から表示までの流れを実際に動かして確認することが大切です。

scanfで整数を受け取れる

%dを指定すると、キーボードから半角の整数を読み取れます。

scanf("%d", &walk_minutes);

入力された整数は変数に保存される

scanfを使う前に、値を保存するint型の変数を用意します。

int walk_minutes;

scanfでは、その変数名の前に&を付けます。

scanf("%d", &walk_minutes);

変数の値はprintfの%dで表示できる

scanfでwalk_minutesに保存された整数は、printfで表示できます。

printf("ウォーキングを%d分行います。\n", walk_minutes);

このとき、printfで使用する変数名には&を付けません。

複数の整数は左から順番に保存される

scanf("%d%d%d", &walk_minutes, &stretch_count, &water_count);

このscanfでは、入力された整数が左から順番に3つの変数へ保存されます。

30 8 5

対応関係は次のとおりです。

30 → walk_minutes
8  → stretch_count
5  → water_count

まずは、次の3行のつながりを意識しながら、入力する整数を変えて何度か実行してみましょう。

int walk_minutes;
scanf("%d", &walk_minutes);
printf("%d\n", walk_minutes);

変数を用意し、scanfで値を入れ、printfで取り出して表示する。この基本の流れを理解できれば、scanfを使った整数入力の第一歩はしっかり身についています。