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;
}
}
If you connect an
istream_iteratorto a stream, thatistream_iteratorwill be valid until the stream it reads from hasfailbitorbadbitset. This only happens if you read malformed data out of the stream, or the stream runs out of data.Because
cinreads data from the standard input stream (which, by default on most systems, is connected to the keyboard), theistream_iteratorcan always read more data. That is, after you’ve entered a list of numbers,cinwon’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
cinto stop reading data, you have several options. First, you can have the OS redirectcinby 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,cinwill encounter the end of file and will triggerfailbit. The loop then terminates.Alternatively, you could explicitly cause
cinto 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 causefailbitto trigger oncin, since it can’t treat the value as a float, and would then cause the loop to exit.Hope this helps!