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;
}
}
3 ответа
Если вы подключите istream_iterator
в поток, что istream_iterator
будет действовать до тех пор, пока поток, из которого он читает failbit
или же badbit
задавать. Это происходит только в том случае, если вы читаете искаженные данные из потока или в потоке данных заканчиваются данные.
Так как cin
считывает данные из стандартного потока ввода (который по умолчанию в большинстве систем подключен к клавиатуре), istream_iterator
всегда можете прочитать больше данных. То есть после того, как вы ввели список номеров, cin
не будет в состоянии ошибки, потому что вы всегда можете ввести больше чисел в программу. Тот факт, что программа "зависает", вызван тем, что она ожидает ввода большего количества данных. Вы можете убедиться в этом, введя дополнительные данные после того, как программа обработает все введенные вами данные.
Вызывать cin
чтобы остановить чтение данных, у вас есть несколько вариантов. Во-первых, вы можете перенаправить ОС cin
путем передачи данных в программу или чтения данных из файла. Например, в системе Linux вы можете запустить вашу программу следующим образом:
./my-program < my-input-file
Как только программа прочитала весь текст из my-input-file
, cin
встретит конец файла и сработает failbit
, Затем цикл завершается.
В качестве альтернативы, вы могли бы явно вызвать cin
попасть в конец файла. В системах Linux, если вы запускаете программирование из командной строки, вы можете нажать CTRL+D, чтобы заставить стандартный ввод отправить сигнал конца файла, что также приведет к выходу из цикла. Кроме того, вы можете ввести недопустимое значение с плавающей запятой в cin
например строка STOP!
, Это вызвало бы failbit
вызвать cin
, поскольку он не может обрабатывать значение как число с плавающей запятой, а затем приведет к выходу из цикла.
Надеюсь это поможет!
Программа работает нормально, просто вы должны указать конец файла в своих входных данных:
echo 1.1 5.3 | ./myprogram
Если вы буквально печатаете на консоли, отправьте Ctrl-D
сигнализировать конец ввода.
(Несомненно, ваше условное if( numbers.size( ) % 2 != 0 )
для ясности и семантики; также выполните компиляцию и учитывайте предупреждения компилятора.)
Стандартный ввод не имеет конца (если вы что-то не передаете ему); это продолжается вечно. Следовательно istream
итератор никогда не достигнет EOF
потому что нет EOF
,