istream_iterator问题,在循环中使用

发布于 2024-11-27 09:40:28 字数 5196 浏览 0 评论 0原文

为什么这个循环不会终止?程序在打印出 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

电影里的梦 2024-12-04 09:40:28

如果您将 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 上触发,因为它不能将该值视为浮点数,然后导致循环退出。

希望这有帮助!

If you connect an istream_iterator to a stream, that istream_iterator will be valid until the stream it reads from has failbit or badbit 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), the istream_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 redirect cin 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:

./my-program < my-input-file

Once the program has read all of the text from my-input-file, cin will encounter the end of file and will trigger failbit. 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 into cin, such as the string STOP!. This would cause failbit to trigger on cin, since it can't treat the value as a float, and would then cause the loop to exit.

Hope this helps!

谁的年少不轻狂 2024-12-04 09:40:28

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

echo 1.1 5.3 | ./myprogram

如果您确实在控制台上键入,请发送 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:

echo 1.1 5.3 | ./myprogram

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.)

揽月 2024-12-04 09:40:28

标准输入没有尽头(除非您通过管道向其输入内容);它永远持续下去。因此,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 the EOF because there is no EOF.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文