C言語のきほん|キーボードから入力してみよう

入力できるようになると、プログラムは“話せる”ようになる。scanfでキーボード入力の第一歩を踏み出そう。

これまでの内容では、printf を使って画面に文字や数値を表示してきました。
でも、プログラムをもっと自由に動かすには、外からデータを受け取る仕組みが必要になります。

そこで登場するのが キーボード入力 です。
C言語では、キーボードから入力された値を取り込む代表的な方法として scanf 関数を使えます。

入力ができるようになると、プログラムは一気に“対話型”になります。

  • 入力された数で計算する
  • 入力された文字で処理を切り替える
  • 入力内容をチェックして結果を表示する

ただし、scanf は printf より少しクセがあり、最初はつまずきやすい関数でもあります。
ここでは、覚えるポイントをしぼりながら、scanf の使い方をやさしく丁寧に説明していきます。

scanf関数とは

scanf は、キーボードから入力されたデータを読み取り、指定した変数に格納する関数です。
入力されたデータを、変換指定によって「どんな形式として読むか」を決めて取り込みます。

scanfの動きのイメージ

つまり、同じ「入力」でも、変換指定と変数の型の組み合わせによって、取り込まれ方が変わるということです。

scanfを使うために必要な準備

scanf を使うには、printf と同じく標準入出力の機能を使うので、先頭に stdio.h を書きます。

#include <stdio.h>

printf を使うときにも書いているので、ここは自然に覚えられるはずです。

scanfの基本の形

scanf は次の形で使います。

scanf(変換指定, データを格納する変数のアドレス);

この中の2つが超重要です。

  • 変換指定:入力をどう解釈して取り込むか
  • 変数のアドレス:どの変数に値を入れるか(入れ先の住所)

変換指定で入力の読み取り方が決まる

scanf では、変換指定で入力の形式を指定します。
よく使うものを先にまとめておきます。

変換指定何として読むか入れる変数の型の例
%d10進整数として読むint
%c1文字として読むchar
%x16進整数として読むunsigned int など
%lf小数として読むdouble

この節の中心は、%c と %x の違いを体験して理解するところです。

変数のアドレスと & の意味

scanf の2つ目の引数は、変数そのものではなく 変数のアドレス を渡します。
アドレスは、メモリ上の住所のようなものです。

C言語では、変数名の前に & を付けると、その変数のアドレスを指定できます。

例:

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

なぜアドレスが必要なのか

scanf は、入力された値を変数に書き込みます。
書き込み先がわからないと保存できないので、変数の場所(アドレス)を渡してあげる必要があります。

入力された値
   ↓
scanfが変数の場所へ書き込む
   ↓
変数に値が入る

最初は「なんで & がいるの?」となりがちですが、
scanf は値を受け取って変数に入れる仕事をするので、入れ先の住所が必要、と覚えるとスッキリします。

同じ A を入力しても結果が変わるのが面白いポイント

ここがこの記事のいちばん大事なところです。
同じ A を入力しても、scanf の変換指定が違うと、入る値の意味が変わります。

  • %c で読む → 文字 A を読む
  • %x で読む → 16進数の A を読む(Aは10)

つまり、同じ入力でも「読み方」を変えるだけで結果が変わります。

サンプルプログラムで試してみよう

ファイル名:5_7_1.c

#include <stdio.h>

int main(void)
{
    char ch;
    unsigned int hex_value;

    /* 1文字として入力する */
    printf("1文字入力してください(例: A)> ");
    scanf("%c", &ch);
    printf("入力した文字を10進数で表示: %d\n", ch);

    /* 16進数として入力する */
    printf("\n16進数を入力してください(例: A)> ");
    scanf("%x", &hex_value);
    printf("入力した値を10進数で表示: %u\n", hex_value);

    return 0;
}

実行結果例(入力はユーザーが打ったもの)

1文字入力してください(例: A)> A
入力した文字を10進数で表示: 65

16進数を入力してください(例: A)> A
入力した値を10進数で表示: 10

同じ A を入力しているのに、1回目は 65、2回目は 10 になります。
この違いがわかれば、scanf の変換指定の重要性がかなりつかめます。

1回目はなぜ 65 になるのか

1回目は %c で読み取っています。

scanf("%c", &ch);

これは「1文字として読む」という意味です。
ch には文字 A が入ります。

でも、printf で %d を使って表示すると、文字は内部の文字コード(数値)として表示されます。
一般的に A の文字コードは 65 なので、65 が出ます。

流れを整理

2回目はなぜ 10 になるのか

2回目は %x で読み取っています。

scanf("%x", &hex_value);

%x は「16進数として読む」という意味です。
16進数では A は 10 を表します。

そのため、hex_value には 10 が入ります。
それを10進数で表示しているので 10 が出ます。

流れを整理

scanfが入力待ちで止まるのは正常

このプログラムを実行すると、プロンプトが表示されたあとに止まったように見えます。
これは scanf が入力待ちになっているためで、正常な動作です。

入力して Enter を押すと、そこで入力が確定し、scanf が値を取り込んで次へ進みます。

scanfが難しいと言われる理由(最初に知っておくと安心な点)

scanf は便利ですが、printf より注意点が多いです。
ここでは、入門で特につまずきやすいポイントだけ押さえておきます。

& を付け忘れると動かない原因になる

scanf では、基本的に変数の前に & が必要です。

  • 正しい例:scanf("%d", &value);
  • 間違いやすい例:scanf("%d", value);

& を忘れると、変数に値が入らなかったり、予期しない動作になったりします。

変換指定と変数の型を合わせる

scanf では、変換指定と変数の型の組み合わせがとても大事です。

  • %c → char
  • %x → unsigned int など

組み合わせがずれると、正しく読み取れない原因になります。

%x で読むときは符号なし整数が基本

文書にもある通り、scanf("%x", &n); のときは n を unsigned int にするのが基本です。
16進数は符号なしの値として扱う場面が多く、規格上もこの組み合わせが想定されています。

unsigned int の詳しい話は後の章で解説しますが、ここでは

  • %x の入力先は unsigned int にしておくと安心

という理解で大丈夫です。

表示と入力はセットで考えると書きやすい

入力処理は、次の流れにするととても書きやすく、ユーザーにも親切です。

  1. printf で入力してほしい内容を表示する
  2. scanf で入力を受け取る
  3. printf で入力結果を表示して確認する

この流れは、入力プログラムの基本の型として覚えておくと便利です。

ここまで理解できれば入力の第一歩はOK

この節でのゴールは、scanf の基本を体験して「入力できた!」を作ることです。

特に次の3点がつかめていれば、かなり良い感じです。

  • scanf が入力待ちになることがわかる
  • 変換指定で読み取り方が変わることがわかる
  • & を付けると変数に値が入ることがわかる

この先は、整数入力、浮動小数点入力、文字列入力へ進むことで、さらに実用的なプログラムが書けるようになります。