[英]istream_iterator behaviour
我有兩段代碼,當在main()
單獨使用它們時,它們可以正常工作。
vector<int> v;
cout << "Enter sequance of integers "<< "(press q to quit) : ";
istream_iterator<int> start_cin(cin);
istream_iterator<int> end_of_cin;
copy(start_cin,end_of_cin,back_inserter(v));
for ( vector<int>::iterator It = v.begin();It != v.end(); It++ )
cout << *It << "\t";
cout << endl;
和
vector<string> vS;
cout << "Enter three strings : ";
for ( int i = 0; i < 3; i++ )
vS.push_back(*istream_iterator<string>(cin));
ostream_iterator<string> sIt(cout,", ");
copy(vS.begin(),vS.end(),sIt);
cout << endl;
這兩個部分一起使用時
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
#include <string>
using namespace std;
int main ()
{
// first part
vector<int> v;
cout << "Enter sequance of integers "<< "(press q to quit) : ";
istream_iterator<int> start_cin(cin);
istream_iterator<int> end_of_cin;
copy(start_cin,end_of_cin,back_inserter(v));
for ( vector<int>::iterator It = v.begin();It != v.end(); It++ )
cout << *It << " \t";
cout << endl;
vector<string> vS;
cout << "Enter three strings : ";
for ( int i = 0; i < 3; i++ )
vS.push_back(*istream_iterator<string>(cin));
ostream_iterator<string> sIt(cout,", ");
copy(vS.begin(),vS.end(),sIt);
cout << endl;
return 0;
}
在這里,第一部分工作了,但是第二部分給出了輸出: Enter Three Strings : , , ,
。 我想知道這種行為的背后原因是什么?
謝謝。
在copy()
完成之后,由於對“整數” q
讀取失敗, cin
將處於無法讀取的狀態( !cin.good()
)。 這意味着隨后的for
循環將無法讀取任何內容。
加:
cin.clear();
cin.ignore(); // To skip the unread "q"
在for
循環之前。
編輯:
如James Kanze所評論,請檢查以確保"q"
是copy()
終止的原因:
...
cin.clear();
string int_read_terminator;
cin >> int_read_terminator;
if ("q" != int_read_terminator)
{
cerr << "Integer copy() failure: " << int_read_terminator << "\n";
}
else
{
...
您剛剛遇到了input_iterator
的問題input_iterator
:它要求整個文件屬於一種類型。 有幾種方法可以解決此問題。 最一般的方法是在實際源和流之間插入一個過濾流。 因此,例如,當您輸入僅帶有'q'
一行時,流的第一部分應終止,例如:
class UntilQStreambuf : public std::streambuf
{
std::streambuf* mySource;
char myBuffer;
bool myIsAtStartOfLine;
protected:
int underflow()
{
int results = mySource->sbumpc();
if ( results == 'q'
&& myIsAtStartOfLine
&& mySource->sgetc() == '\n' ) {
mySource->sbumpc(); // remove terminator line.
results = traits_type::eof();
}
if ( results != traits_type::eof() ) {
myBuffer = results;
setg( &myBuffer, &myBuffer, &myBuffer + 1 );
}
return results;
}
public:
UntilQStreambuf( std::istream& source )
: mySource( source->rdbuf() )
, myIsAtStartOfLine( true )
{
}
};
(我認為boost::iostream
有一些支持,這將使編寫起來非常簡單。)然后,您可以使用std::cin
的streambuf
(或任何地方)設置一個單獨的流來讀取數字:
std::vector<int>
getNumbers( std::istream& source )
{
UntilQStreambuf localSB( source );
std::istream src( &localSB );
std::vector<int> results( (std::istream_iterator<int>( src )),
(std::istream_iterator<int>()) );
if ( !src.eof() ) {
// Some other error occurred...
}
return results;
}
通過使用單獨的流,將不會在原始流中設置結束條件,您可以稍后再繼續(也許使用更多相同的技術)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.