まず、「Enter キーを押す」ことは、改行文字 ( ) を入力シーケンスに入力する以外に、IOStream にとって特別な意味はありません\n
(テキスト ストリームを使用する場合、プラットフォーム固有の行末シーケンスは単一の改行文字に変換されることに注意してください)。コンソールにデータを入力すると、データは通常、コンソールによって行バッファリングされ、Enter キーを押したときにのみプログラムに転送されます (通常、これはオフにできますが、詳細はプラットフォーム固有であり、この質問には関係ありません)。
s.get(buffer, n)
これで、 forの動作std::istream s
と、少なくともn
文字の配列へのポインターに注意を向けることができますbuffer
。これが何をするかの説明は非常に簡単です: を呼び出しますs.get(buffer, n, s.widen('\n'))
。について話しているstd::istream
のに、おそらく を変更していないので、単に return を返すstd::locale
と想定できます。つまり、呼び出しは がデリミタと呼ばれる場所と同等であり、問題はこの関数が何をするかになります。s.widen('\n')
'\n'
s.get(buffer, n, '\n')
'\n'
さて、この関数は文字まで抽出し、到達したとき、または次の文字がストリームに残っている区切り文字と同じになったときm = 0 < n? n - 1: 0
に停止します (区切り文字を抽出したい場合に使用しました)。null 文字が location に格納されている場合、抽出された文字は と の対応する場所に格納されます。万一、文字を抽出しない場合を設定します。m
std::istream::getline()
buffer
0 < n
buffer[n - 1]
std::ios_base::failbit
OK、これでなぞなぞのすべての要素が整ったはずです: 少なくとも 1 文字で 5 文字未満の文字を入力すると、最初の への呼び出しがget()
成功し、バッファ内の次の文字として改行文字が残されました。さらに多くの文字を試みると、get()
すぐに区切り文字が見つかり、文字は保存されず、設定によって失敗が示されましたstd::ios_base::failbit
。この理論を検証するのは簡単です:
#include <iostream>
int main()
{
char buffer[5];
for (int count(0); std::cin; ++count) {
if (std::cin.get(buffer, 5)) {
std::cout << "get[" << count << "]='" << buffer << "'\n";
}
else {
std::cout << "get[" << count << "] failed\n";
}
}
}
文字を入力しない場合、 への最初の呼び出しはstd::cin.get()
失敗します。1 ~ 4 文字を入力すると、最初の呼び出しは成功しますが、2 回目の呼び出しは失敗します。4 文字を超える文字を入力すると、2 番目の呼び出しも成功するなどです。スタックしている可能性のある改行文字に対処するには、いくつかの方法があります。
- これが読み取りを停止した理由である場合は、と同じよう
std::istream::getline()
に動作しますstd::istream::get()
が、区切り文字も抽出します。これにより、1 行が複数の読み取りに分割される場合がありますが、これは望ましい場合とそうでない場合があります。
- 固定行の長さの制限を回避するには、 (つまり)
std::getline()
と一緒に使用できます。std::string
std::getline(std::cin, string)
- 成功した後、必要に応じ
get()
て次の文字が改行であるかどうかを確認できstd::istream::peek()
ますstd::istream::ignore()
。
これらのアプローチのどれがニーズを満たすかは、何を達成しようとしているかによって異なります。