08 標準入力(scanf)

前章では printf() で画面に出力することを学んだ。
この章では scanf() を使って、キーボードからデータを受け取る方法を学ぶ。


08-1 標準入力とは

キーボードからの入力を標準入力(standard input)と呼ぶ。
標準入力からデータを読み取る関数が scanf() である。

printf()scanf() はちょうど対になっている。

関数方向役割
printf()プログラム → 画面データを出力する
scanf()キーボード → プログラムデータを受け取る

08-2 Visual Studio の設定(SDL チェックを無効にする)

Visual Studio では scanf() を使うと、次のようなエラーが出てビルドできない場合がある。

error C4996: 'scanf': This function or variable may be unsafe.

これは Visual Studio のセキュリティ開発ライフサイクル(SDL)チェックという機能が、
古い関数の使用を警告しているためである。
この授業では scanf() をそのまま使えるよう、プロジェクトの設定を変更する。

設定手順

1 メニューの 「プロジェクト」→「プロパティ」 をクリックする
2 左側のツリーで 「構成プロパティ」→「C/C++」→「全般」 を選ぶ
3 右側の一覧で 「SDL チェック」 を見つけ、「いいえ(/sdl-)」 に変更する
4 「OK」 をクリックして閉じる
⚠ この設定はプロジェクト全体に適用される。一度設定すれば以降は不要。
設定後にもう一度 Ctrl+F5 を押してビルドし直すこと。

08-3 scanf() の基本構文

scanf("書式指定子", &変数名);

printf() との大きな違いが2つある。

printf()scanf()
変数の渡し方 変数名(値を渡す) &変数名(場所を渡す)
書式指定子 %d %f など %d %lf など(一部異なる)
&(アンパサンド)は「変数のアドレス(場所)」を意味する。
scanf() は「読み取った値をどこに入れるか」を知る必要があるため、
変数の値ではなく変数のある場所を渡す。詳しくはポインタの章で学ぶ。

scanf で使う書式指定子

書式指定子注意
int%d
double%lfprintf では %f だが scanf では %lf
float%f
char%c
文字列(char[]%s空白の手前まで読み取る
double の読み取りには %lf を使う。
printf では %f で表示できるが、scanf%f を使うと正しく読み取れない。

08-4 実行例:整数を入力して表示する

08_01_inputInt.c
#include <stdio.h>

int main(void)
{
    int number;

    printf("整数を入力してください: ");
    scanf("%d", &number);
    printf("入力された値は %d です¥n", number);

    return 0;
}

実行例(42 と入力した場合):

整数を入力してください: 42
入力された値は 42 です
scanf() の前に printf() で入力を促すメッセージを表示するのが基本的なパターン。

08-5 実行例:2つの整数を入力して計算する

08_02_inputTwo.c
#include <stdio.h>

int main(void)
{
    int x, y;

    printf("2つの整数を入力してください(スペースで区切る): ");
    scanf("%d %d", &x, &y);

    printf("x + y = %d¥n", x + y);
    printf("x - y = %d¥n", x - y);
    printf("x * y = %d¥n", x * y);
    printf("x / y = %d¥n", x / y);   /* y が 0 のときは注意 */
    printf("x %% y = %d¥n", x % y);

    return 0;
}

実行例(10 3 と入力した場合):

2つの整数を入力してください(スペースで区切る): 10 3
x + y = 13
x - y = 7
x * y = 30
x / y = 3
x % y = 1
y0 を入力するとゼロ除算が発生してプログラムが異常終了する(05章で確認済み)。

08-6 実行例:実数・文字列を入力する

08_03_inputDouble.c
#include <stdio.h>

int main(void)
{
    double height;
    double weight;

    printf("身長(cm)を入力してください: ");
    scanf("%lf", &height);   /* double は %lf で読み取る */

    printf("体重(kg)を入力してください: ");
    scanf("%lf", &weight);

    printf("身長: %.1f cm¥n", height);
    printf("体重: %.1f kg¥n", weight);

    return 0;
}

実行例:

身長(cm)を入力してください: 170.5
体重(kg)を入力してください: 65.2
身長: 170.5 cm
体重: 65.2 kg
08_04_inputString.c
#include <stdio.h>

int main(void)
{
    char name[20];   /* 最大19文字の文字列を格納できる配列 */

    printf("名前を入力してください: ");
    scanf("%s", name);   /* 文字列は & 不要 */
    printf("こんにちは、%s さん!¥n", name);

    return 0;
}

実行例:

名前を入力してください: Taro
こんにちは、Taro さん!
⚠ 文字列(char[])は配列なので & を付けない。
また %s はスペースの手前まで読み取る。Yamada Taro のようにスペースを含む名前は途中で切れる。

08-7 演習

📝 演習① 正方形の面積を求めるプログラム

一辺の長さを入力して、正方形の面積を表示するプログラムを作れ。

08_05_square.c
#include <stdio.h>

int main(void)
{
    /* ここにコードを書く */

    return 0;
}

実行例(5 と入力した場合):

一辺の長さを入力してください: 5
正方形の面積は 25 です
答えの例を表示
#include <stdio.h>

int main(void)
{
    int side;

    printf("一辺の長さを入力してください: ");
    scanf("%d", &side);
    printf("正方形の面積は %d です¥n", side * side);

    return 0;
}
📝 演習② 三角形の面積を求めるプログラム

底辺と高さを入力して、三角形の面積を表示するプログラムを作れ。
面積の公式:底辺 × 高さ ÷ 2

08_06_triangle.c
#include <stdio.h>

int main(void)
{
    /* ここにコードを書く */

    return 0;
}

実行例(底辺 6.0・高さ 4.0 を入力した場合):

底辺を入力してください: 6.0
高さを入力してください: 4.0
三角形の面積は 12.00 です
ヒントを表示
答えの例を表示
#include <stdio.h>

int main(void)
{
    double base, height, area;

    printf("底辺を入力してください: ");
    scanf("%lf", &base);

    printf("高さを入力してください: ");
    scanf("%lf", &height);

    area = base * height / 2.0;
    printf("三角形の面積は %.2f です¥n", area);

    return 0;
}
📝 演習③ 自己紹介を表示するプログラム

名前と年齢を入力して、自己紹介文を表示するプログラムを作れ。

08_07_selfIntro.c
#include <stdio.h>

int main(void)
{
    /* ここにコードを書く */

    return 0;
}

実行例:

名前を入力してください: Hanako
年齢を入力してください: 18
私の名前は Hanako です。18歳です。よろしくお願いします。
答えの例を表示
#include <stdio.h>

int main(void)
{
    char name[20];
    int  age;

    printf("名前を入力してください: ");
    scanf("%s", name);

    printf("年齢を入力してください: ");
    scanf("%d", &age);

    printf("私の名前は %s です。%d歳です。よろしくお願いします。¥n", name, age);

    return 0;
}

08-8 理解度チェック

Q1. scanf() で変数に & を付ける理由として正しいものはどれか。

解説を表示

正解:イ

scanf() は読み取った値を「どこに入れるか」を知る必要があるため、変数のアドレスを渡す。& なしでは正しく動作しない。

Q2. double 型の変数を scanf() で読み取るとき、正しい書式指定子はどれか。

解説を表示

正解:ウ

scanfdouble を読み取るときは %lf(エル・エフ)を使う。printf では %f でよいが、scanf では区別が必要。

Q3. 文字列を scanf() で読み取るとき、正しい書き方はどれか。

解説を表示

正解:イ

配列名はすでにアドレスを表しているため、& は不要。%s で文字列を読み取る。

Q4. scanf("%s", name);"Yamada Taro" と入力したとき、name に入る文字列はどれか。

解説を表示

正解:イ

%s はスペースの手前まで読み取る。Yamada までが name に入り、Taro は読み取られない。


08-9 まとめ

項目内容
SDL チェックプロジェクトのプロパティで「いいえ」に設定する(1回だけ)
scanf() の構文scanf("書式指定子", &変数名);
& の意味変数のアドレスを渡す。文字列(配列)には不要
double の読み取り%lf(printf は %f でよいが scanf は %lf
文字列の注意%s はスペースの手前まで。スペースを含む入力は読み取れない