istringstream
を使用して、単純な文字列を一連の整数に分割しようとしています。
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main(){
string s = "1 2 3";
istringstream iss(s);
while (iss)
{
int n;
iss >> n;
cout << "* " << n << endl;
}
}
そして私は得る:
* 1
* 2
* 3
* 3
最後の要素が常に2回出てくるのはなぜですか?それを修正する方法は?
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.5 (while (iss)
は、このシナリオのwhile (iss.eof())
と同じです)。
具体的には、3回目のループ反復で、iss >> n
が成功して3
を取得し、ストリームを良好な状態のままにします。次に、この良好な状態のためにループが4回実行され、次の(4番目の)iss >> n
が失敗して初めて、ループ条件が解除されます。ただし、その4回目の反復が終了する前に、4回目にn
...を出力します。
試してください:
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
string s = "1 2 3";
istringstream iss(s);
int n;
while (iss >> n) {
cout << "* " << n << endl;
}
}
お役に立てれば:
iss:1 2 3
反復1
iss:1 2 3(最初は)
n = 1
iss:2 3
// * 1が出力されます
反復2:
iss:2 3(最初は)
n = 2
iss:3
// * 2が出力されます
反復3
iss:3
n = 3
iss: ''
反復4
iss: ''
nは変更されません//ストリームからの入力がないため、issのeofにフラグが設定されます
iss: ''
そして、上記の投稿で正しく言及されているように、while(iss)はwhile(iss.eof())と同じです。
内部的に、function(istream :: operator >>)は、最初に sentry オブジェクト(noskipwsをfalseに設定)を作成することによって入力シーケンスにアクセスします[これは、スペースがセパレーターであり、リストであることを意味します1,2,3])になります。次に( good [ここではeofに到達していません])、 num_get :: get [次の整数を取得]を呼び出して、抽出操作と解析操作の両方を実行し、それに応じて、ストリームの内部状態フラグが立てられます。最後に、それは戻る前に歩哨オブジェクトを破壊します。
参照: http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/