[英]istream_iterator behaviour
I have two pieces of code.They work properly when it is used alone in the main()
. 我有两段代码,当在
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;
and 和
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;
When these two part use together,ie 这两个部分一起使用时
#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;
}
here first part worked but second part give output: Enter Three Strings : , , ,
. 在这里,第一部分工作了,但是第二部分给出了输出:
Enter Three Strings : , , ,
。 I want to know that what is the reason behind this behaviour? 我想知道这种行为的背后原因是什么?
Thanks. 谢谢。
After the copy()
has completed cin
will be in an unreadable state ( !cin.good()
), due to the failed read of the "integer" q
. 在
copy()
完成之后,由于对“整数” q
读取失败, cin
将处于无法读取的状态( !cin.good()
)。 This means the subsequent for
loop will fail to read anything. 这意味着随后的
for
循环将无法读取任何内容。
Add: 加:
cin.clear();
cin.ignore(); // To skip the unread "q"
before the for
loop. 在
for
循环之前。
EDIT: 编辑:
As commented by James Kanze , check to ensure "q"
was the cause of the termination of the copy()
: 如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
{
...
You've just encountered one of the problems with input_iterator
: it requires the entire file to be of one type. 您刚刚遇到了
input_iterator
的问题input_iterator
:它要求整个文件属于一种类型。 There are several ways of working around this; 有几种方法可以解决此问题。 the most general is to insert a filtering streambuf between the actual source and the stream.
最一般的方法是在实际源和流之间插入一个过滤流。 Thus, for example, the first part of your stream should terminate when you enter a single line with just a
'q'
, something like: 因此,例如,当您输入仅带有
'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 )
{
}
};
(I think boost::iostream
has some support which would make this significantly simpler to write.) You then set up a separate stream for reading the numbers, using the streambuf
from std::cin
(or whereever): (我认为
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;
}
By using a separate stream, the end condition won't be set in the original stream, and you can continue with it later (perhaps using more of the same technique). 通过使用单独的流,将不会在原始流中设置结束条件,您可以稍后再继续(也许使用更多相同的技术)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.