web-dev-qa-db-ja.com

2つの異なるgetline()関数があるのはなぜですか(実際にある場合)?

C++コード行の簡単なスニペットを作成するたびに

std::string s;
cin >> s;

行全体を取得するのではなく、空白で停止することを忘れたので、私は自分自身を呪います。

次に、getlineを思い出すと、私は常に2つの種類について混乱します。

std::string s;
getline (std::cin, s);

そして:

char cs[256];
std::cin.getline (cs, sizeof (cs));

データ型以外に、これら2つの間に実際に違いはありますか?

私には、C++の方法は前者でなければならないようです。とにかくnullで終了する文字配列の代わりに実際の文字列を使用する必要があるとすると、どのような状況で後者を使用しますか?

そして、入力は実際には入力ストリームの範囲である必要があるので、なぜistreamの前の部分ではないのですか?

24
paxdiablo

標準ライブラリは、IOStream、String、STLの3つの(主要な)部分に加えて、グッズやCヘッダーが含まれているもので構成されていることに注意してください。

これらのパーツを疎結合しても、奇妙なことは何も見られません(そうでないことを望みますが)。

その他の不一致は次のとおりです。std::string::length vs std::string::size、後者はSTLとのインターフェース互換性のために追加され、前者は古いコードとの互換性のために保持されています。

10
Matthieu M.

グローバル getline() 関数はC++ std :: string オブジェクトで動作します。

istream :: getline() メソッドは「クラシック」C文字列(charへのポインタ)で機能します。

25

これは一般的なインターフェイス設計の問題です。 cin.getline()はリクエストを行う自然な方法ですが、ストリームコードが_<string>_に依存することを避けるために、cin.getline(std::string&)関数を提供することはできません。独立したgetline(cin, s)は、文字列がスコープに取り込まれると、後で追加できます。 _char*_には何もないので、_#include_にとっては問題ありません-とにかく言語のすべての部分。

ある意味では、言語が後のコードで既存のクラス(Rubyなど)にさらに関数を追加できるようになると便利ですが、他の方法では、非局在化が噛み付き、保守性が損なわれます。そしてもちろん、最小限のメンバー関数と多くの独立した関数についての一般的な議論があります。私は個人的に、インターフェースを直感的で表現力のないものにするためにとられるべきではなく、それぞれ独自のものであると考えています。

7
Tony Delroy

はい、最新のC++の方法は、free関数を使用して、std :: stringを入力することです。

しかし、IOStreamにはstd :: stringよりもはるかに長い歴史があり(標準バージョンは少なくとも同じデザインの3番目の化身です)、その歴史は物事がそのようになっている理由を説明しています。

(getlineメンバーには、動的割り当てを意味しないという利点があります。その特性は、いつでも便利ですが、ゼロからの設計でそれを正当化するにはおそらく十分ではありません)。

1
AProgrammer

Iostreamsライブラリ内のgetlineバリアントはターゲットとして文字列をサポートしていないため、文字列ライブラリはサポートするバリアントを定義しました。

1
Simon Richter