第11回 | C言語のscanfで入力を受け取る:キーボードから値を読む基本| UNIX Cafe

* 当サイトでは、コンテンツの一部に広告を掲載しています。

System Note $ cat /proc/ai-disclosure

本記事の構成および論理分析にはAI(人工知能)を使用しています。情報の正確性は、システム管理者(UNIXユーザー)による手動検証済みです。

第11回|C言語のscanfで入力を受け取る:キーボードから値を読む基本

はじめてのC言語 | 第11回

目次

はじめに

前回は、文字と文字列の基本を学びました。
今回は、キーボードから入力を受け取る方法を扱います。

この回の目的は次の4点です。

  • scanf の基本形を理解する
  • 整数を入力として受け取れるようにする
  • 変数のアドレスを渡す理由を知る
  • 初学者がつまずきやすい点を先に押さえる

scanf とは何か

scanf は、ユーザーがキーボードから入力した値を読み取り、変数に保存するための関数です。

C言語では、プログラムの実行中にユーザーから値を受け取りたい場面があります。
たとえば、年齢、点数、個数、番号などを入力してもらい、その値を使って計算や判定を行う場合です。

このようなときに使うのが scanf です。

scanf は「標準入力」から値を読み取ります。
標準入力とは、プログラムにデータを入力するための基本的な入り口のことで、通常はキーボードからの入力を指します。

最初のサンプルコード

ソースコード

input_number.c という名前で保存します。

#include <stdio.h>

int main(void) {
    int age;

    printf("age: ");
    scanf("%d", &age);

    printf("You entered: %d\n", age);

    return 0;
}

このサンプルでは、scanf の基本形をわかりやすく見るために、入力に失敗した場合の処理は省略しています。実用的なプログラムでは、scanf の戻り値を確認して、入力が正しく読み取れたかを判定します。

実行手順

1. 作業ディレクトリに移動する

cd ~/Desktop

2. コンパイルする

clang input_number.c -o input_number

3. 実行する

./input_number

4. 値を入力する

実行すると、次のように表示されます。

age:

ここで 20 と入力して Enter キーを押します。

実行例:

age: 20
You entered: 20

コードの読み方

int age;

入力された整数を保存するための変数 age を宣言しています。

printf("age: ");

入力を促すメッセージを表示しています。

scanf("%d", &age);

ここが入力を受け取る部分です。

  • %d : 整数を読み取る
  • &age : 読み取った値を age に格納する場所を渡す

printf("You entered: %d\n", age);

入力された値を確認のために表示しています。

なぜ &age と書くのか

scanf("%d", &age);& は、変数 age の場所、つまりアドレスを渡すための記号です。

scanf は入力された値を、指定された変数に書き込みます。
そのためには「値そのもの」ではなく、「どこに書き込めばいいか」という場所の情報が必要です。

int age;
scanf("%d", &age);

この場合、

&age

は「age がメモリ上のどこにあるか」を表します。

たとえるなら、

age

は「箱の中身」、

&age

は「箱の住所」です。

scanf は入力された数値をその箱に入れたいので、箱そのものではなく、箱の住所を受け取ります。

つまり、

scanf("%d", &age);

は、整数を入力して、その値を age という変数の場所に保存してくださいという意味です。

もし & を付けずに、

scanf("%d", age);

と書くと、age の値をアドレスだと勘違いして使おうとします。
その結果、正しく動かなかったり、プログラムが異常終了したりします。

少し分解すると、こうなります。

int age;

これは整数を入れる変数を用意しています。

&age

これは age のアドレスです。

scanf("%d", &age);

これは、そのアドレスに入力値を書き込ませています。

なお、文字列を入力するときの配列では、少し見え方が変わります。

char name[20];
scanf("%s", name);

この場合は &name ではなく name と書くことが多いです。
配列名 name 自体が、先頭要素のアドレスのように扱われるからです。

まとめると、

scanf("%d", &age);

この行の & は、age に入力値を入れるために、age のアドレスを scanf に渡しているという意味です。

整数を2つ入力する例

scanf では、複数の値をまとめて読み取ることもできます。

#include <stdio.h>

int main(void) {
    int x;
    int y;

    printf("x y: ");
    scanf("%d %d", &x, &y);

    printf("x = %d\n", x);
    printf("y = %d\n", y);

    return 0;
}

実行例:

x y: 10 20
x = 10
y = 20

入力するときは、空白で区切って 10 20 のように書けます。

入力した値で計算する例

#include <stdio.h>

int main(void) {
    int a;
    int b;

    printf("a b: ");
    scanf("%d %d", &a, &b);

    printf("sum = %d\n", a + b);

    return 0;
}

実行例:

a b: 3 5
sum = 8

入力を使うと、毎回違う値でプログラムを試せます。

文字列入力は最初は分けて考える

scanf は文字列入力にも使えますが、初学者向けにはまず整数入力から確実に理解する方が安全です。
文字列入力は、配列サイズや空白の扱いで混乱しやすいためです。

この回では、int 型の入力に絞って理解していきます。

scanf で遊んでみる:隠れた数字を当てる!

#include <stdio.h>

int main(void) {
    int secret = 42; // 秘密の数字
    int guess;       // ユーザーの予想
    int count = 0;   // 挑戦回数

    printf("1から100の間で、僕が隠した数字を当ててみてね!\n");

    while (count < 5) { // 5回まで挑戦可能
        printf("予想を入力してね。(残り%d回):", 5 - count);
        scanf("%d", &guess);

        if (guess == secret) {
            printf("大当たり!やったね!\n");
            break; // 正解したらループを抜ける
        } else if (guess < secret) {
            printf("もっと大きいよ。\n");
        } else {
            printf("もっと小さいよ。\n");
        }
        count++;
    }

    if (count == 5) {
        printf("残念、正解は %d だったよ!\n", secret);
    }

    return 0;
}

実行結果:

1から100の間で、僕が隠した数字を当ててみてね!
予想を入力してね。(残り5回):50
もっと小さいよ。
予想を入力してね。(残り4回):40
もっと大きいよ。
予想を入力してね。(残り3回):45
もっと小さいよ。
予想を入力してね。(残り2回):43
もっと小さいよ。
予想を入力してね。(残り1回):42
大当たり!やったね!

ポイントは、次の条件です。

while (count < 5)

簡単な解説

このプログラムは、ユーザーが入力した数値と、あらかじめ用意した secret の値を比べるゲームです。

  • secret には正解の数字を入れておく
  • scanf("%d", &guess); で予想した数字を受け取る
  • if 文で、正解・小さい・大きいを判定する
  • count++; で挑戦回数を1回ずつ増やす

while (count < 5) は「挑戦回数が5回未満の間だけ繰り返す」という意味です。正解した場合は break; でループを抜けるので、残り回数があってもゲームはそこで終わります。

自分で改造してみよう

サンプルが動いたら、少しだけ値やメッセージを変えて遊んでみましょう。

  • int secret = 42; の数字を別の値に変える
  • while (count < 5)while (count < 10) に変えて、挑戦回数を増やす
  • 「もっと大きいよ」「もっと小さいよ」のメッセージを自分の言葉に変える
  • 正解したときや失敗したときの表示を、もっとゲームらしくしてみる

入力を受け取るプログラムは、値を少し変えるだけでゲームらしくなります。まずは決まった数字を当てる形で試し、慣れてきたら次の回以降で学ぶ機能と組み合わせて、さらに広げていきましょう。

初心者がつまずきやすい点

age ではなく &age

整数を scanf で読むときは、変数名だけではなく & を付けます。

正しい例:

scanf("%d", &age);

誤った例:

scanf("%d", age);

後者は誤りです。

%d は整数用

%dint 型の入力に使います。
型が違うのに %d を使うと、正しく読み取れません。

入力待ちの状態で止まって見える

scanf を使ったプログラムは、入力されるまで先に進みません。
止まっているように見えても、入力待ちであることがあります。

scanf の戻り値も重要

技術的には、scanf は読み取りに成功した個数を返します。
初学者向けでも、この点は早めに知っておくと安全です。

たとえば、整数を1つ読むなら、成功時は 1 が返ります。

より安全な書き方

#include <stdio.h>

int main(void) {
    int age;

    printf("age: ");

    if (scanf("%d", &age) != 1) {
        printf("Input error\n");
        return 1;
    }

    printf("You entered: %d\n", age);

    return 0;
}

このコードでは、整数として正しく読めなかった場合にエラーとして終了します。

なぜ戻り値を確認するのか

scanf は、入力を読み取ったあと、正しく読み取れた項目の数を戻り値として返します。

たとえば %d で整数を読み取ろうとしているときに、数字ではなく文字を入力すると、期待どおりに読み取れないことがあります。

このようなとき、scanf の戻り値を確認すると、入力に失敗したことを検出できます。

初学者向けの最初の段階では、まずは次のような基本形を覚えれば大丈夫です。

scanf("%d", &age);

そのあとで、必要に応じて戻り値を確認する書き方を加えていきます。

if (scanf("%d", &age) != 1) {
    printf("入力が正しくありません。\n");
    return 1;
}

実務や安全なコードでは、入力が必ず成功するとは限らないため、戻り値を確認する方が適切です。

よくあるエラー

warning: format specifies type ‘int *’ but the argument has type ‘int’

原因: & を付け忘れています。

誤った例:

scanf("%d", age);

正しい例:

scanf("%d", &age);

数字以外を入れて期待した結果にならない

原因: %d は整数を期待しているためです。
文字列や記号を入力すると、読み取りに失敗します。

入力が複数あるのに書式が合っていない

たとえば、2つ入力したいのに %d が1つしかないと正しく読めません。

正しい例:

scanf("%d %d", &x, &y);

練習用コード

整数を1つ入力して表示する

#include <stdio.h>

int main(void) {
    int number;

    printf("number: ");
    scanf("%d", &number);

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

    return 0;
}

整数を2つ入力して合計を表示する

#include <stdio.h>

int main(void) {
    int x;
    int y;

    printf("x y: ");
    scanf("%d %d", &x, &y);

    printf("%d\n", x + y);

    return 0;
}

まとめ

今回のポイントは次のとおりです。

  • scanf を使うとキーボードから値を読み取れる
  • int を読むときは %d を使う
  • scanf には変数の場所を渡すので、& と変数名を続けて書く
  • 入力待ちで止まって見えるのは正常な動作である
  • より安全にするなら scanf の戻り値を確認する

この回では、scanf を使って整数入力を受け取る方法を確認しました。
表示だけだったプログラムに入力が加わると、動きのあるプログラムを書けるようになります。

次回予告

次は、ポインタの基本を学びます。
今回登場した &amp;ageのような書き方の正体も、ここでしっかり理解できるようになります。

最初は少し難しく感じるかもしれませんが、心配はいりません。ひとつずつ、ゆっくり進めていきましょう。

復習してみよう

復習したい方は、こちらもあわせてご覧ください。

C言語の次にUnityやUnreal Engineを学ぶ選択肢

用途ごとに選ぶ C言語のおすすめ本

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

のいのアバター のい UNIX Cafe マスター

Macintosh Color Classicから始まった旅は、長いWindows時代を経て、Windows10のサポート終了をきっかけにUNIXの世界へ戻ってきました。UNIX Cafeでは、UNIX・Linux・そしてMacな世界を、むずかしい言葉を使わず、物語のように書いています。プログラミングは、アイデアをコンピューターに伝えるための言葉です。簡単な単語と文法を覚えれば、誰でもコマンドを使えます。ぜひ一度、やさしいプログラミングの世界をのぞいてみてください。

目次