【问题标题】:istream_iterator question, using in loopistream_iterator 问题,在循环中使用
【发布时间】:2011-07-30 23:51:31
【问题描述】:

为什么这个循环不会终止?程序在打印出 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;
    }
}  

【问题讨论】:

  • 如果您希望对最终代码进行代码审查,请考虑将其发布到 codereview.stackexchange.com。 Stack Overflow 主要用于编码问题,而 Code Review 主要用于代码审查。 :-)

标签: c++ stl istream-iterator


【解决方案1】:

如果将istream_iterator 连接到流,则istream_iterator 将一直有效,直到它读取的流设置了failbitbadbit。仅当您从流中读取格式错误的数据或流中的数据用完时才会发生这种情况。

因为cin 从标准输入流(大多数系统默认连接到键盘)读取数据,istream_iterator 总是可以读取更多数据。也就是说,在您输入数字列表后,cin 将不会处于错误状态,因为您始终可以在程序中输入更多数字。程序“冻结”的事实是由于它正在等待输入更多输入。在程序处理完您输入的所有数据后,您可以通过输入更多数据来验证这一点。

要使cin 停止读取数据,您有多种选择。首先,您可以让操作系统重定向cin,方法是将数据传送到程序中或从文件中读取数据。例如,在 Linux 系统上,您可以这样运行程序:

./my-program < my-input-file

一旦程序读取了来自my-input-file 的所有文本,cin 将遇到文件结尾并触发failbit。然后循环终止。

或者,您可以明确地使cin 到达文件末尾。在 Linux 系统上,如果您从命令行运行程序,您可以按 CTRL+D 使标准输入发送文件结束信号,这也会导致循环退出。或者,您可以在cin 中输入一个无效的浮点值,例如字符串STOP!。这将导致failbitcin 上触发,因为它不能将值视为浮点数,然后会导致循环退出。

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    程序运行良好,只是您必须在输入中提供文件结尾:

    echo 1.1 5.3 | ./myprogram
    

    如果您是在控制台上打字,请发送 Ctrl-D 以表示输入结束。

    (无关紧要,为了清晰和语义,您的条件可能应该阅读if( numbers.size( ) % 2 != 0 );另外,请务必使用编译器警告进行编译。)

    【讨论】:

      【解决方案3】:

      标准输入没有尽头(除非你用管道传递给它);它继续永远。因此,istream 迭代器永远不会真正到达EOF,因为没有EOF

      【讨论】:

      • 我错误地否决了它;编辑问题以添加其他格式,然后投票。干杯! :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2016-10-23
      • 2022-01-07
      相关资源
      最近更新 更多