gets

高木です。おはようございます。

昨日宣言したように、当面はマニアックなネタ、それも規格では非推奨、あるいは廃止されたものを蘇らせる方向で突き進みます。

今回は、CやC++ではその代表格ともいえるgets関数を蘇らせることにします。

gets関数というと、バッファオーバーランが検出できない危険な関数ということで知られています。
ところが、手軽に1行分の文字列を標準入力から読み込むには、これほど手軽な関数はありません。
fgets関数で代替するようにいわれても、そもそもの関数仕様が違うので、単純に置き換えただけではすみません。

C++には、std::stringを引数に取るstd::getline関数があります。
この関数ならgetsと同じぐらい手軽ですが、単純な配列に読み込みたい場合には大がかりすぎるのです。

だから、やはりgets関数なのです。
今回は、C++を使って、gets関数と同じように使えるにもかかわらず、バッファオーバーランその他の問題を解消する関数を再設計&実装してみます。

今回も単にインクルードするだけで使えるようにしています。
とりあえず、ヘッダーファイルにはgets関数と関連関数だけ実装していますがが、今後、増やしていけたらと考えています。

今回の実装にあたって、flockfile関数、funlockfile関数、getc_unlocked関数が必要になりました。
互換性のために、Windows(Visual C++とMinGW-w64)向けにそれらの代替関数を実装しています。
LinuxやCygwinなどでは、処理系が持つ同名の関数を使っています。

今回の再設計では、getsの第1引数には配列型のオブジェクトしか渡せないようにしています。
格納可能な文字数を別途渡してもよかったのですが、getsと同じように使えることを優先しました。
とはいえ、別途サイズを渡せるようにしたほうが便利なこともあるので、それについては今後の課題とします。

それ以外に工夫した点として、オプションで第2引数を渡せるようにしました。
配列の要素数の範囲内で改行文字を読み取らなかったことを判定できるようにしています。
例外を送出することも考えたのですが、さすがにちょっとやり過ぎですからね。

<dradnats/cstdio>のダウンロード

コメントを残す

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