大阪市中央区 システムソフトウェア開発会社

営業時間:平日09:15〜18:15
MENU

gets

株式会社クローバーフィールドの経営理念
著者:高木信尚
公開日:2017/04/04
最終更新日:2018/06/20
カテゴリー:技術情報

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

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

今回は、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>のダウンロード

    前の記事 :
    次の記事 :
    上に戻る