C言語の基本

【C言語】scanf関数でキーボードから数値を入力をしてみよう!

トビタカ
トビタカ
本記事では、C言語でキーボードから数値を入力する方法をご紹介しています。

キーボードから数値を読み取るコードの書き方とは…?

 

C言語でキーボードから数値を入力することってできないの…?

 

前回の記事で変数を使えるようになりました!

【必ず使う】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つあるんです。

 

キーボードから数値を入力するときには、次の2つに気をつける必要があります。

  1. 変数の型式と変換指定子を合わせる必要がある
  2. 変数に保存できない型式のデータを入力してはいけない

 

①変数の型式と変換指定子を合わせる必要がある

1つ目の注意点は『変数の型式』と『変換指定子』を合わせる必要があることです。

これまでたくさん使ってきたprintf関数を思い出してください。

『整数なら%d』『実数なら%f』のように、変数の型式によって変換指定子を変えてきたと思います。

でも、変換指定子を変え忘れて、実数を%dで表示させようとすると、数値がおかしくなったことがありましたよね?

scanf関数でも似たようなことが起きるので、プログラムを正しく動かすためには、変換指定子を合わせる必要があります。

とび助
とび助
たしかに3.14を%dで表示したら、とんでもない数値になった気がします…
トビタカ
トビタカ
そうならないためにも、変換指定子をよくチェックしましょう、

 

②変数に保存できない型式のデータを入力してはいけない

2つ目の注意点は、変数に保存できない文字や数値を入力してはいけないことです。

試しに先ほどのプログラムを実行して1を11個入力してみてください。

とび助
とび助
なんかよく分からない結果になりました…
トビタカ
トビタカ
はい。バグるんですよ…

 

scanf関数で変数に保存できないデータを入力しようとすると、盛大にバグります。

ここで言う『保存できないデータ』というのは、『変数の保存範囲を越えた数値』や『型式の異なるデータ』のことですね。

このようなデータを入力してしまうと、保存した数値が変わったり、よく分からない記号が表示されたりするんです。

トビタカ
トビタカ
先程はintの上限である2,147,483,647を越えたからバグったんです。
とび助
とび助
そういうことなんですね~

 

このように、scanf関数では2つの注意点を守らないとバグります。

このバグはバッファオーバーフロー(バッファオーバーラン)と呼ばれるものなんです。

とび助
とび助
でも、表示がバグるだけなら、大したことありませんよね…?
トビタカ
トビタカ
う~ん…実はこのバグ、結構ヤバイんですよ…

バッファオーバーフローは超危険

一見、バッファオーバーフローは表示される数値がバグるだけのように見えますが、実は非常に危険なバグなんです。

というのも、PCのメモリを破壊してしまう可能性があるからです。

 

以前、変数の記事で『データは大きさを変更できるロッカーのような場所に保存している』とご説明したと思います。

【必ず使う】C言語の変数って一体何なの…?宣言・初期化のやり方もご紹介! 変数って一体何なの…? 前回の記事で『文字や数値を画面に表示する方法』をマスターすることができました。 ...

 

では、もしこのロッカーより大きなデータを保存しようとしたら、一体どうなるのでしょうか?

とび助
とび助
エラーでプログラムが止まるんじゃないですか…?
トビタカ
トビタカ
いいえ。ロッカーを破壊して、データを保存します。

 

一見、ロッカーに入りきらないデータは保存できないように思えますよね。

でも、実際には回りのロッカーを破壊してでもデータを保存しようとするんです。

もし、破壊されたロッカーに何かしらのデータが保存されていたら、そのデータを上書きしてしまうことになるのです。

とび助
とび助
データを上書きするだけじゃ、あんまりやばくなさそうですけど…
トビタカ
トビタカ
もし、破壊したロッカーに超重要なデータがあったとしたら…?
とび助
とび助
それはヤバそうです!

 

ご存知のとおり、PCはExcelやメールソフトなどのアプリを同時に動かすことができます。

つまり、複数のアプリでメモリのロッカーを分けあっているのです。

言い換えれば、実行したプログラムで使っていないメモリには、他のアプリで使っているデータが保存されているんですよ。

このデータをバッファオーバーランで勝手に上書きしてしまうと、アプリが正常に動かなくなってしまう可能性があるんです。

トビタカ
トビタカ
販売した製品でこのようなことが起きると、品質問題になります。
とび助
とび助
それはヤバイっすね…

 

アプリの強制終了程度なら、ソフトのアップデートで済むので、何とかなるかもしれません。

でも、もしPCなどの機械を動かすのに必要なデータを上書きしてしまったら…

リコールや返品処理等が必要になり、1億円以上の損害が発生することだってあるんです。

トビタカ
トビタカ
バッファオーバーランを起こさないために、scanfを禁止している会社も多いんです!
とび助
とび助
じゃあscanf関数は使えないんですか…?
トビタカ
トビタカ
勉強で使うくらいなら全然問題ありませんよ!

練習で作るような小さいプログラムであれば、バッファオーバーフローになっても、あまり影響はありません。

ほんの少しバグるだけなので、練習でガンガン使って行きましょう!

なお、実際の開発で使用されることが多いデータの入力方法は『sscanf』『fgetc』『fgets』などです。

これらの関数は多少クセがあるので、使い方に関しては後日ご紹介いたします。

scanf関数でバッファオーバーフローを防ぐ方法

とび助
とび助
バッファオーバーフローが怖すぎてscanf関数が使えません…
トビタカ
トビタカ
大丈夫です!対処法がありますよ!

実はscanf関数でバッファオーバーフローを防ぐ方法があります。

変換指定子に次のような細工をすればいいんです。

scanfを安全にした例

scanf(“%9d”, &i);

とび助
とび助
%とdの間に数値を入れると何が変わるんですか…?
トビタカ
トビタカ
入力する数値の桁数を制限できるんです。

 

『%9d』のように変換指定子の間に数値を書いておくと、読み取る桁数を指定できます

先程の例であれば、9桁の数値を変数に保存することができるのです。

int型の保存範囲は-2,147,483,648〜2,147,483,647でしたよね?

なので、9桁の整数を読み取るようにすれば、必ず保存範囲に収まります。

つまり、バッファオーバーフローを防ぐことができるんです。

トビタカ
トビタカ
この方法を使ってテンキーで数値を入力すれば安心ということです!
とび助
とび助
それは安心ですね!

実はこの方法には注意点があります。

それは、指定した桁数以上の数値を入力すると、次のscanf関数に影響が出ることです。

例えば、%3dで12345と入力すると、変数には123が保存されるのですが、保存されなかった45は次の入力に回されます。

そのため、次のscanf関数で1と入力しても、451が保存されてしまうのです。

トビタカ
トビタカ
今はこのような現象があることを知っておくだけでOKです。
とび助
とび助
わかりました!

入力した数値を複数の変数に保存する方法

とび助
とび助
scanf関数で同時に2つの数値を読み取ることってできないんですか…?
トビタカ
トビタカ
もちろんできますよ!

 

キーボードから読み取ったデータを複数の変数に保存したい場合は、次のようなコードを書けば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』が『,』で区切られていることが読み取れると思います。

このように読取形式に書いたとおりに入力すれば、複数の数値を一度に読み取ることができるんです。

トビタカ
トビタカ
『%lf %lf』や『%lf_%lf』なども指定できますよ!
とび助
とび助
入力の仕方も自分で選べるんですね!

入力ミスやバッファオーバーフローが起きてしまいそうなときは、強制停止させましょう。

『Ctrl』と『C』を同時に押すことで、プログラムを強制終了することができますよ。

まとめ

以上がC言語でキーボードから数値を入力する基本的な方法です。

scanf関数は実際の開発ではあまり使いませんが、プログラムの練習にはうってつけの方法になります。

しばらくはscanf関数を使いまくって、いろいろな機能をもつプログラムを作ってみてくださいね。

scanfで数値を入力する方法のまとめ
トビタカ
トビタカ
今はバッファオーバーフローを気にせずに、たくさんのプログラムを書いてみましょう!
とび助
とび助
ガンガン練習していきます!

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

【意外と簡単】C言語の変数に代入して計算をしてみよう! 変数で計算をするには、どのようなコードを書けばいいの…? ついに変数と数値の入力方法をマスターしましたね!...

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA