istream_iterator问题,在循环中使用
为什么这个循环不会终止?程序在打印出 istream_iterator 中的所有元素后冻结。
/*30*/ int main( int arc, char **arv ) {
/*31*/ vector<float> numbers( 0 );
/*32*/ cout << "Please, input even number of floats: ";
/*33*/ istream_iterator<float> iit (cin);
/*34*/ istream_iterator<float> eos;
/*35*/ while( iit != eos ) {
/*36*/ cout << (*iit) << endl;
/*37*/ iit++;
/*38*/ }
/*39*/ if( numbers.size( ) & 1 == 1 ) {
/*40*/ cerr << "Sorry: you must input"
/*41*/ << " an even number of inputs" << endl;
/*42*/ }
/*43*/ return ( 0 );
/*44*/ }
更新:
所以现在这使得更多。谢谢大家。根据提供的信息,我将事情简化为更少的行。需要重新输入模数部分,但这对我来说现在更清楚了。
34 int main( int arc, char **arv ) {
35 vector<float> num;
36 cout << "Please, input even number of floats: ";
37 for( istream_iterator<float> iit (cin);
38 iit!=istream_iterator<float>( );iit++ ) {
39 num.push_back( (*iit) );
40 }
41 }
更新 2:如果有人仍在阅读此主题,我可以从社区获得有关“最终”产品的内容/风格反馈吗?
/********************************************************************
* Author: Mattew Hoggan
* Description: Write a client program that uses the data type point.
* Read a sequence of points (pairs of floating-point numbers) from
* standard input, and find the one that is closest to the first.
* *****************************************************************/
#include <math.h>
#include <iostream>
#include <vector>
#include <istream>
#include <iterator>
#include <algorithm>
#include <limits.h>
using namespace std;
typedef struct point {
float x;
float y;
} point;
float calc_distance( const point *a, const point *b ) {
return sqrt( pow( a->x-b->x, 2.0 ) + pow( a->y-b->y, 2.0 ) );
}
void print_point( point *a ) {
cout << "(" << a->x << ", " << a->y << ") ";
}
void delet_point( point *a ) {
delete a;
}
vector<point*>* form_pairs( vector<float> &num ) {
vector<point*> *points=NULL;
if( ( num.size( ) & 1 ) == 1 ) {
cerr << "ERROR: You input: " << num.size( )
<< " which is odd, failed to build vector "
<< endl;
return points;
} else {
cout << "Going to build points" << endl;
points = new vector<point*>;
for( vector<float>::iterator vit=num.begin( );
vit!=num.end( ); vit+=2 ) {
point *in = new point( );
in->x = *(vit);
in->y = *(vit+1);
points->push_back( in );
}
return points;
}
}
void pop_front( vector<point*> *pairs ) {
reverse( pairs->begin( ), pairs->end( ) );
pairs->pop_back( );
reverse( pairs->begin( ), pairs->end( ) );
}
void min_euclidean_distance( vector<point*> *pairs ) {
if( pairs->size( ) == 1 ) {
cerr << "You already know the answer to this" << endl;
return;
}
point *first = pairs->front( );
pop_front( pairs );
point *second = pairs->front( );
pop_front( pairs );
for_each( pairs->begin( ),pairs->end( ),print_point );
cout << endl;
point *p_min = second;
float f_min = calc_distance( first,second );
for( vector<point*>::iterator pit = pairs->begin( );
pit != pairs->end( ); pit++ ) {
float tmp = calc_distance( first,(*pit) );
if( tmp < f_min ) {
f_min = tmp;
p_min = (*pit);
}
}
cout << "The closest node to "; print_point( first );
cout << " is "; print_point( p_min );
cout << " at " << f_min << " units away " << endl;
delete first;
delete second;
}
int main( int arc, char **arv ) {
vector<float> num;
cout << "Please, input even number of floats: ";
for( istream_iterator<float> iit (cin);
iit!=istream_iterator<float>( );iit++ ) {
num.push_back( (*iit) );
}
vector<point*>* pairs = form_pairs( num );
if( pairs ) {
min_euclidean_distance( pairs );
for_each( pairs->begin( ),pairs->end( ),delet_point );
delete pairs;
}
}
Why will this loop not terminate? The program freezes after it prints out all the elements in the istream_iterator.
/*30*/ int main( int arc, char **arv ) {
/*31*/ vector<float> numbers( 0 );
/*32*/ cout << "Please, input even number of floats: ";
/*33*/ istream_iterator<float> iit (cin);
/*34*/ istream_iterator<float> eos;
/*35*/ while( iit != eos ) {
/*36*/ cout << (*iit) << endl;
/*37*/ iit++;
/*38*/ }
/*39*/ if( numbers.size( ) & 1 == 1 ) {
/*40*/ cerr << "Sorry: you must input"
/*41*/ << " an even number of inputs" << endl;
/*42*/ }
/*43*/ return ( 0 );
/*44*/ }
Update:
So this now make more since. Thanks all. With the information provided I simplified things to less lines. Need to get the modulus part back in, but that is a lot more clear to me now.
34 int main( int arc, char **arv ) {
35 vector<float> num;
36 cout << "Please, input even number of floats: ";
37 for( istream_iterator<float> iit (cin);
38 iit!=istream_iterator<float>( );iit++ ) {
39 num.push_back( (*iit) );
40 }
41 }
Update 2: If anyone is still reading this thread, can I get content/style feedback from the community on the "final" product?
/********************************************************************
* Author: Mattew Hoggan
* Description: Write a client program that uses the data type point.
* Read a sequence of points (pairs of floating-point numbers) from
* standard input, and find the one that is closest to the first.
* *****************************************************************/
#include <math.h>
#include <iostream>
#include <vector>
#include <istream>
#include <iterator>
#include <algorithm>
#include <limits.h>
using namespace std;
typedef struct point {
float x;
float y;
} point;
float calc_distance( const point *a, const point *b ) {
return sqrt( pow( a->x-b->x, 2.0 ) + pow( a->y-b->y, 2.0 ) );
}
void print_point( point *a ) {
cout << "(" << a->x << ", " << a->y << ") ";
}
void delet_point( point *a ) {
delete a;
}
vector<point*>* form_pairs( vector<float> &num ) {
vector<point*> *points=NULL;
if( ( num.size( ) & 1 ) == 1 ) {
cerr << "ERROR: You input: " << num.size( )
<< " which is odd, failed to build vector "
<< endl;
return points;
} else {
cout << "Going to build points" << endl;
points = new vector<point*>;
for( vector<float>::iterator vit=num.begin( );
vit!=num.end( ); vit+=2 ) {
point *in = new point( );
in->x = *(vit);
in->y = *(vit+1);
points->push_back( in );
}
return points;
}
}
void pop_front( vector<point*> *pairs ) {
reverse( pairs->begin( ), pairs->end( ) );
pairs->pop_back( );
reverse( pairs->begin( ), pairs->end( ) );
}
void min_euclidean_distance( vector<point*> *pairs ) {
if( pairs->size( ) == 1 ) {
cerr << "You already know the answer to this" << endl;
return;
}
point *first = pairs->front( );
pop_front( pairs );
point *second = pairs->front( );
pop_front( pairs );
for_each( pairs->begin( ),pairs->end( ),print_point );
cout << endl;
point *p_min = second;
float f_min = calc_distance( first,second );
for( vector<point*>::iterator pit = pairs->begin( );
pit != pairs->end( ); pit++ ) {
float tmp = calc_distance( first,(*pit) );
if( tmp < f_min ) {
f_min = tmp;
p_min = (*pit);
}
}
cout << "The closest node to "; print_point( first );
cout << " is "; print_point( p_min );
cout << " at " << f_min << " units away " << endl;
delete first;
delete second;
}
int main( int arc, char **arv ) {
vector<float> num;
cout << "Please, input even number of floats: ";
for( istream_iterator<float> iit (cin);
iit!=istream_iterator<float>( );iit++ ) {
num.push_back( (*iit) );
}
vector<point*>* pairs = form_pairs( num );
if( pairs ) {
min_euclidean_distance( pairs );
for_each( pairs->begin( ),pairs->end( ),delet_point );
delete pairs;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您将
istream_iterator
连接到流,则该istream_iterator
将一直有效,直到它读取的流具有failbit
或badbit设置。仅当您从流中读取格式错误的数据或流用完数据时,才会发生这种情况。
由于 cin 从标准输入流(默认情况下在大多数系统上连接到键盘)读取数据,因此 istream_iterator 始终可以读取更多数据。也就是说,在您输入数字列表后,
cin
不会处于错误状态,因为您始终可以在程序中输入更多数字。程序“冻结”的事实是由于它正在等待输入更多输入。您可以在程序处理完您输入的所有数据后输入更多数据来验证这一点。要使 cin 停止读取数据,您有多种选择。首先,您可以通过将数据传输到程序或从文件中读取数据来让操作系统重定向 cin。例如,在 Linux 系统上,您可以这样运行程序:
一旦程序从
my-input-file
读取了所有文本,cin
将遇到文件结尾并将触发failbit
。然后循环终止。或者,您可以显式地使 cin 到达文件末尾。在 Linux 系统上,如果您从命令行运行编程,则可以按 CTRL+D 使标准输入发送文件结束信号,这也会导致循环退出。或者,您可以在
cin
中输入无效的浮点值,例如字符串STOP!
。这将导致failbit
在cin
上触发,因为它不能将该值视为浮点数,然后导致循环退出。希望这有帮助!
If you connect an
istream_iterator
to a stream, thatistream_iterator
will be valid until the stream it reads from hasfailbit
orbadbit
set. This only happens if you read malformed data out of the stream, or the stream runs out of data.Because
cin
reads data from the standard input stream (which, by default on most systems, is connected to the keyboard), theistream_iterator
can always read more data. That is, after you've entered a list of numbers,cin
won't be in an error state because you can always enter more numbers into the program. The fact that the program is "freezing" is caused by the fact that it's waiting for more input to be entered. You can verify this by entering more data after the program processes all the data that you've entered.To cause
cin
to stop reading data, you have several options. First, you can have the OS redirectcin
by piping data into the program or reading the data out of a file. For example, on a Linux system, you could run your program like this:Once the program has read all of the text from
my-input-file
,cin
will encounter the end of file and will triggerfailbit
. The loop then terminates.Alternatively, you could explicitly cause
cin
to hit the end-of-file. On Linux systems, if you're running the programming from the command-line, you can press CTRL+D to cause standard input to send an end-of-file signal, which would also cause the loop to exit. Alternatively, you could enter an invalid floating-point value intocin
, such as the stringSTOP!
. This would causefailbit
to trigger oncin
, since it can't treat the value as a float, and would then cause the loop to exit.Hope this helps!
该程序运行良好,只是您必须在输入中提供文件结束符:
如果您确实在控制台上键入,请发送
Ctrl-D
来表示输入结束。(与此无关,为了清晰和语义,您的条件可能应该阅读
if(numbers.size( ) % 2 != 0 )
;另外,请使用编译器进行编译并注意编译器警告。)The program works fine, it's just that you have to provide an end-of-file in your input:
If you're literally typing on the console, send
Ctrl-D
to signal the end of the input.(Unrelatedly, your conditional should probably read
if( numbers.size( ) % 2 != 0 )
for clarity and semanticity; also, do compile with and heed compiler warnings.)标准输入没有尽头(除非您通过管道向其输入内容);它永远持续下去。因此,
istream
迭代器实际上永远不会到达EOF
,因为没有EOF
。Standard input has no end (unless you pipe something to it); it continues forever. Therefore, the
istream
iterator will never actually reach theEOF
because there is noEOF
.