本日はC言語における入力用関数・scanf()関数について解説します。
目次 閉じる
目次
なぜ入力関数が必要なのか
当然ですが、直接プログラムに数値を書き込めば、その決まった数値でのみプログラムが実行されます。
つまりそれは、「そのプログラムでは、毎回同じ計算しかできない」ことを意味します。
これでは、別の数値で計算したくなった場合、プログラムを書き直す必要が出てきます。
面倒臭すぎて、プログラミングをしている意味が皆無ですね。
いちいち数値打ち直すようじゃ無理か….
数値はね、読み込まないと。

謎のエンジニアの言う通り、実はC言語にはキーボードからの数値の入力を可能にする関数が存在します。
それがscanf()関数です。scan()じゃないので御用心を。
scanf()関数の使い方
画面に表示するときにprintf()関数を使用したように、キーボードから入力するときはscanf()関数を使用します。
scanf()関数は以下のように使います。
scanf("入力変換指定子",&変数名);
入力変換指定子とは、入力された数字をどのように変換するかを表す指定子です。printf()関数で使用した出力指定子と同じように使用可能です。
変数名には、入力されたデータを記憶しておく変数名を指定します。scanf()関数を使う場合は、変数名の前に&をつける必要があります。この&には変数のアドレスを知らせる意味があります。
この関数を実行すると、プログラムは入力待ち状態になります。
そしてプログラムを使う人が、データを入力してリターン(Enter)キーを押すと、そのデータが指定した変数に代入されます。
なお、scanf()関数を使用するには #include<stdio.h> が必要です ( printf()関数利用時も必要 )。
数値の入力
これだけのことがわかれば、キーボードからデータ入力することができます。
次のプログラムはscanf()関数を使用し、入力された数値をそのまま表示する例です。
#include<stdio.h>
int main(){
int a;
scanf("%d",&a);//入力部分
printf("%d¥n",a);
return 0;
}
実行結果は以下のようになります。なお、コメント部分は説明用に書き加えた文なので実際には出力されません。
810 //入力値
810 //出力値
このプログラムを実行したら、入力待ち状態になります。そこで数値を入力し、リターンキーを押すと、その数値がそのまま出力されます。当然数値は810以外でも構いません。
実はscanf()関数では、整数だけではなく、実数も入力可能です。
ただし、実数を入力する場合は%lf指定子を使用する必要があります。
printf()関数では%f指定子ですので、注意が必要です。
次のプログラムは、scanf()関数を使用して入力された実数をそのまま表示する例です。
#include<stdio.h>
int main(){
double a;
scanf("%lf",&a);//入力部分
printf("%f¥n",a);
return 0;
}
上のコードの実行結果は以下になります。コメント部分は説明用に付け加えたやつなので、実際は出力されません。
1145.14 //入力値
1145.140000//出力値
複数の入力
scanf()関数は、1度に1つのデータしか入力できないような頭の悪い子ではではありません。
指定子を複数使うことで、複数の入力を1度に実行可能です。
次のプログラムでは、scanf()関数を使用して2つの数値を入力し、表示します。
#include<stdio.h>
int main(){
int a,b;
scanf("%d %d",&a,&b);//入力部分
printf("%d, %d¥n",a,b);
return 0;
}
このプログラムの実行結果の例は以下のようになります。
1919 810 //入力値
1919, 810 //出力値
2つの数値を別々の型で入力することも可能です。
“%d %lf”という指定子を与えると、1つ目は整数、2つ目は実数値で入力できます。
また、区切る記号を指定して入力することも可能で、この場合は2つの指定子の間に、区切る記号を指定します。
次のプログラムでは , で区切って2つの数値を入力させます。
#include<stdio.h>
int main(){
int a,b;
scanf("%d,%d",&a,&b); //入力部分
printf("%d , %d",a,b);
return 0;
}
実行結果は以下
1919,810 //入力値
1919 , 810 //出力値
今回は入力するとき、”,”で区切る必要があります。その代わり、スペースなどで区切れなくなるので注意が必要です。
シグマ計算をやってみよう
それでは実践的なコード書いていこうと思います。
皆さん数Ⅱでやったシグマ計算を覚えていますか?私はこれを書くまですっかり忘れていました。
しかしながら基本的にはそこまで難しくありません。1+2+3+4+5+…………+100などを計算するのがシグマです。
単純にするために、最小値minから最大値maxの間の整数の合計値を求めることにします。
合計値sumを求める公式は以下のようになります。
sum = ( min + max ) × ( max – min +1 )÷ 2
ここまで分かればあとはコーディングするだけですね!
#include<stdio.h>
int main(){
int min,max,sum;
printf(”最小値,最大値 :”);
scanf("%d,%d",&min,&max);//入力部分
sum =(min+max)*(max-min+1)/2;//計算部分
printf("%d~%d の合計は%dです。¥n",min,max,sum);//出力部分
return 0;
}
このプログラムの実行結果は以下のようになります。
最小値,最大値 :114,514
114~514 の合計は125914です。
このプログラムでは、入力・計算・出力の3段階に分かれています。
このうち、計算と出力はひとまとめにすることも可能ですが、分かりやすくするために敢えて分割しています。
注意点
入力ミスが脅威に
ここからはscanf()関数のデメリットについてお話ししていこうと思います。
実はscanf()関数はいろいろな問題を抱えています。入門書では比較的よく使われるにもかかわらず、本格的な開発では使用されません。
会社によってはscanf()関数禁止令が出されていることもあります。
しかし、先ほど作ったプログラムはいずれも特に問題なく動作していました。
一体どこに問題があるのかというと、それは入力ミスです。
正しく使用している限り、scanf()関数は特に問題を引き起こしませんが、入力ミスがあった途端、恐ろしい問題を引き起こす可能性があります。
これから、先ほどのプログラムを題材に、入力ミスのケースを紹介していきます。
区切り記号のミス
まず起こりそうな例として、区切り記号を打ち間違えてみます。
先ほどのプログラムでは、,で区切るようになっていましたが、これを敢えて無視してスペースで区切ります。
以下は、区切り記号を入力ミスした場合の実行結果です。
最小値,最大値 :100 200
100~1 の合計は-4949です。
はじめに入力した100の方は正常に入力されているようですが、後の200の方はなぜか1という数字になってしまっています。
この結果は使用するコンパイラによって変わってくるので、皆さんが実行させてみた場合は別の結果が出るかもしれません。
大きすぎる数値を入力した場合
次に極端に大きい数値を入力してみます。
最近のコンパイラはかなり大きな数でも入力できてしまうので、もしご自身で試される際は、16ビットコンパイラを使ってください。
以下は、大きすぎる数値を入力した場合の実行結果です。
最小値,最大値 :1,999999999999999
1~-1530494977 の合計は-845365248です。
先ほどと同じく、2つ目の値と、計算結果が明らかに異なっていることがわかります。
文字列を入力した場合
さらに狂った実験をしたいと思います。数値を入力しろと言われているのに、文字列を入力してみます。結果は以下。
最小値,最大値 :ABCDEF
-341704624~1 の合計は-751766615です。
ABCDEFを入力してみました。やはり出力が滅茶苦茶ですね。
解決法
実はこの問題の解決は簡単ではありません。
解決策としては、文字列として入力させて、そのデータを解析する方法が一般的です。
文字列処理の方法についてはまた別の投稿で解説するので、もう少しお待ちください。
この問題が簡単に解決できるものではない、ということだけ覚えておいてください。
最後に
本日はscanf()関数について解説しました。
簡単なようで、少し注意が必要な部分がいくつかありましたね。
何度も書きながら、C言語をマスターしていきましょう。
ご覧いただきありがとうございました!