キーボードから数値を読み取るコードの書き方とは…?
C言語でキーボードから数値を入力することってできないの…?
前回の記事で変数を使えるようになりました!

でも、変数の値を変えるときに、いちいちコンパイルしなおすのは、ちょっと面倒ですよね?
そんな煩わしさからは、今日でおさらばです。
本記事でご紹介する『C言語でキーボードから数値を入力する方法』を身に付ければいいんですよ。
そうすれば、プログラムの数値を簡単に変えられるようなるので、ぜひ一緒に勉強していきましょう!
キーボードから入力した数値を変数に保存する方法

C言語では、次のようなコードを書くことで、キーボードで入力した値を変数に保存することができます。
scanf(“読取形式”,&変数);
少し難しく感じたかもしれませんが、実際には『scanf(“%d”, &i);』というようなシンプルなコードです。
このコードを書けば、キーボードで入力した整数を変数iに保存することができます。
カッコ内の左側の読取形式にはprintf関数でも使った変換指定子を使います。
保存先の変数が整数なら『%d』、実数(double)なら『%lf』を選択しましょう。
変換指定子が決まったら『,』で区切ってから『数値を保存したい変数』を書いてください。
scanf関数では変数の前に『&』を付ける必要があります。
詳細は別の記事でご紹介いたしますが、変数に『&』をつけると『変数のアドレス』を表すことができるんです。
アドレスとは『ロッカーの場所を示す情報』のようなもので、『&』を付けると保存場所を指定できるようになります。
scanf関数の基本的な使い方は、たったこれだけです。
このコードを実行することで、キーボードからの入力待ちの状態になります。
整数を入力してEnterを押せば、入力した整数を変数に代入して保存することができますよ。
#include<stdio.h>
int main(void) {
int i;
printf("数値を入力してください→");
scanf("%d", &i);
printf("入力した数値は%dです!\n", i);
return 0;
}
このプログラムを実行すると、『数値を入力してください→』と表示されて、プログラムの動作が止まります。
これがキーボードからの入力を待っている状態です。
では、さっそく『100』を入力してみましょう。
1つ目のprintf関数には『/n』を付けていないので、『数値を入力してください→100』のようになるはずです。
このままEnterキーを押せば、変数iに100が代入されます。
その結果、改行されてから『入力した数値は100です!』という文章が表示されるのです。
キーボードから数値を入力するときの注意点

キーボードから数値を入力するときには、次の2つに気をつける必要があります。
- 変数の型式と変換指定子を合わせる必要がある
- 変数に保存できない型式のデータを入力してはいけない
①変数の型式と変換指定子を合わせる必要がある
1つ目の注意点は『変数の型式』と『変換指定子』を合わせる必要があることです。
これまでたくさん使ってきたprintf関数を思い出してください。
『整数なら%d』『実数なら%f』のように、変数の型式によって変換指定子を変えてきたと思います。
でも、変換指定子を変え忘れて、実数を%dで表示させようとすると、数値がおかしくなったことがありましたよね?
scanf関数でも似たようなことが起きるので、プログラムを正しく動かすためには、変換指定子を合わせる必要があります。
②変数に保存できない型式のデータを入力してはいけない
2つ目の注意点は、変数に保存できない文字や数値を入力してはいけないことです。
試しに先ほどのプログラムを実行して1を11個入力してみてください。
scanf関数で変数に保存できないデータを入力しようとすると、盛大にバグります。
ここで言う『保存できないデータ』というのは、『変数の保存範囲を越えた数値』や『型式の異なるデータ』のことですね。
このようなデータを入力してしまうと、保存した数値が変わったり、よく分からない記号が表示されたりするんです。
このように、scanf関数では2つの注意点を守らないとバグります。
このバグはバッファオーバーフロー(バッファオーバーラン)と呼ばれるものなんです。
バッファオーバーフローは超危険

一見、バッファオーバーフローは表示される数値がバグるだけのように見えますが、実は非常に危険なバグなんです。
というのも、PCのメモリを破壊してしまう可能性があるからです。
以前、変数の記事で『データは大きさを変更できるロッカーのような場所に保存している』とご説明したと思います。

では、もしこのロッカーより大きなデータを保存しようとしたら、一体どうなるのでしょうか?
一見、ロッカーに入りきらないデータは保存できないように思えますよね。
でも、実際には回りのロッカーを破壊してでもデータを保存しようとするんです。
もし、破壊されたロッカーに何かしらのデータが保存されていたら、そのデータを上書きしてしまうことになるのです。
ご存知のとおり、PCはExcelやメールソフトなどのアプリを同時に動かすことができます。
つまり、複数のアプリでメモリのロッカーを分けあっているのです。
言い換えれば、実行したプログラムで使っていないメモリには、他のアプリで使っているデータが保存されているんですよ。
このデータをバッファオーバーランで勝手に上書きしてしまうと、アプリが正常に動かなくなってしまう可能性があるんです。
アプリの強制終了程度なら、ソフトのアップデートで済むので、何とかなるかもしれません。
でも、もしPCなどの機械を動かすのに必要なデータを上書きしてしまったら…
リコールや返品処理等が必要になり、1億円以上の損害が発生することだってあるんです。
練習で作るような小さいプログラムであれば、バッファオーバーフローになっても、あまり影響はありません。
ほんの少しバグるだけなので、練習でガンガン使って行きましょう!
なお、実際の開発で使用されることが多いデータの入力方法は『sscanf』『fgetc』『fgets』などです。
これらの関数は多少クセがあるので、使い方に関しては後日ご紹介いたします。
scanf関数でバッファオーバーフローを防ぐ方法

実はscanf関数でバッファオーバーフローを防ぐ方法があります。
変換指定子に次のような細工をすればいいんです。
scanf(“%9d”, &i);
『%9d』のように変換指定子の間に数値を書いておくと、読み取る桁数を指定できます。
先程の例であれば、9桁の数値を変数に保存することができるのです。
int型の保存範囲は-2,147,483,648〜2,147,483,647でしたよね?
なので、9桁の整数を読み取るようにすれば、必ず保存範囲に収まります。
つまり、バッファオーバーフローを防ぐことができるんです。
実はこの方法には注意点があります。
それは、指定した桁数以上の数値を入力すると、次のscanf関数に影響が出ることです。
例えば、%3dで12345と入力すると、変数には123が保存されるのですが、保存されなかった45は次の入力に回されます。
そのため、次のscanf関数で1と入力しても、451が保存されてしまうのです。
入力した数値を複数の変数に保存する方法

キーボードから読み取ったデータを複数の変数に保存したい場合は、次のようなコードを書けばOKです。
#include<stdio.h>
int main(void) {
double i;
double j;
printf("2つの実数を『,』で区切って入力してください→");
scanf("%lf,%lf", &i, &j);
printf("入力した実数は%fと%fです!\n", i, j);
return 0;
}
このプログラムを実行したら、試しに『3.14,1.23』と入力してみてください。
きっと、『入力した実数は3.140000と1.230000です!』と表示されたと思います。
先程のプログラムのscanf関数に注目してください。
読取形式の部分に2つの『%lf』が『,』で区切られていることが読み取れると思います。
このように読取形式に書いたとおりに入力すれば、複数の数値を一度に読み取ることができるんです。
入力ミスやバッファオーバーフローが起きてしまいそうなときは、強制停止させましょう。
『Ctrl』と『C』を同時に押すことで、プログラムを強制終了することができますよ。
まとめ
以上がC言語でキーボードから数値を入力する基本的な方法です。
scanf関数は実際の開発ではあまり使いませんが、プログラムの練習にはうってつけの方法になります。
しばらくはscanf関数を使いまくって、いろいろな機能をもつプログラムを作ってみてくださいね。

次はお待ちかねの変数を使った四則演算ですよ!
