【C言語解説】 『 scanf 』 と 『 gets 』 の違いとは?
学校のC言語の実習で標準入力は『 scanf 』なんですが、以前プログラミング練習問題の解説を見たときは『 gets 』と記述されていました。
結局どちらも同じ入力処理を行っています。
じゃあどっちがええんや???
2つあるということは、何か違いもあるはず!
…てなわけで調べてみました。
『 gets 』は危険な関数?
例えば
char str[10];
と宣言すると、
|0|1|2|3|4|5|6|7|8|9|
| | | | | | | | | |\0|
イメージとしてはこんな感じで文字列配列が宣言されます。
配列の最後([9])には文字列の終わりを意味する『 \0 』が入るので実質9文字まで入力することが出来ます。
し・か・し
char str[10]; gets(str);
のように『 gets 』で入力処理をすると、その制限を超えて入力することが出来てしまい、えらいことが起きてしまいます。なので危険なのです。
その代わりに
fgets(str, 10, stdin);
fgets(str, sizeof str, stdin);
という風にサイズ指定した入力処理を使います。
※サイズ指定のミスを防ぐために後者の方が尚良。
それで、何が違うの?
すみません、『 fgets 』が登場したので、
『 fgets 』『 gets 』『 scanf 』の違いを比較しますね。
『 fgets 』
『 fget 』は、Enterキーを押すまでの内容(サイズ範囲内)がそのまま入力されます。
改行コード(\n)自体も入力されます。
『 gets 』
『 gets 』は、Enterキーを押すまでの内容が全て入力されますが、末尾の改行コード(\n)だけは削除されます。
『 scanf 』
『 scanf 』は、Enterキー、スペースが押されるとそれ以降は入力されません(同一視されるため)。つまり、
char str[20]; scanf("%s", str); /* ここで「This is a pen.」と入力しても 「This」しか入力されないということ。 */なので、文章全体を入力したい場合には。。。。
char str1[10], str2[10], str3[10], str4[10]; scanf("%s %s %s %s", str1, str2, str3, str4); /* ここで「This is a pen.」と入力すると str1に「This」, str2に「is」, str3に「a」, str4に「pen.」が入力される。 */ちなみに『 scanf 』は文字列の末尾に改行コードは入力されません。
こんな使い分けがあったんですね!!勉強になりました。