C言語での一行入力の方法
普段はC++を使って、プログラムをかいているせいで、C言語でプログラムを書くときになって少し戸惑ったのでそのことについて書きます。
これは、普段C言語を書いている人は当たり前のことだと思います。
戸惑ったことは、一行入力です。
一行入力とは
一行入力は、通常、ターミナルなどからの入力をイメージした場合に、scanf関数を使うことが多いと思いますが、scanf関数は改行の他に、空白も入力の区切りと判定します。
ここで、この空白を含めて一行全ての入力をひとつの入力としたものを一行入力といいます。
この一行入力は主に、文字列の入力などで使われます。
一行入力の方法
私は、C言語で一行入力をしようとしたときに、C++と混同して戸惑ってしまいました。
C++では、一行入力をするための関数としてgetline関数というものがあるのですが、私はC言語にも同じものがあると勘違いしてコンパイルエラーを出してしまいました。
C言語では、一行入力をするための関数として、fgets関数やgets関数があります。そして、getline関数というものはC言語にはありません。
関数の使い方
ここでは、関数の使い方としてfgets関数の使い方を説明します。
gets関数もあるのですが、この関数はバッファオーバーランという脆弱性をはらんでいるために、今では使うことが推奨されていません。なので、ここではバッファーオーバーランの対策がとられており、gets関数の代わりによく使われるfgets関数の説明をします。
(一部コンパイラでは、gets関数がエラーで使えなかったりします)
使い方は、至って簡単です。
#include <stdio.h>
int main(void)
{
char str[127];
fgets(str, 127, stdin);
printf("%s", str);
return 0;
}
このプログラムは、一行入力として最大126文字を受け取り、それをそのまま表示しています。
fgets関数の使い方は、第1引数に入力を格納するchar型の配列の変数を記述し、第2引数には入力として受け取る最大文字数を記述し、第3引数にはstdinと記述する。
第3引数のstdinは、コンソールからの入力を受け取るということを指定しています。
ちなみに、第2引数の指定によってgets関数で発生する可能性があった、バッファオーバーランを防いでいます。
fgets関数の注意点として、入力の終わりを示すNULL文字が入力の末尾に追加されていますが、そのひとつ前には改行文字が入っています。なので、指定した最大文字数は、NULL文字の分を含めて指定した最大文字数-1の数だけ受け取ることができますが、そこには、改行文字が含まれているので、実際のところは指定した最大文字数-2となります。
さいごに
まだまだ未熟者なので、C言語とC++を両方書いていると、たまに情報を混同することがあります。
今後は戒めたいと思います。