使用 cin::fail() 从标准输入进行无限循环读取

Posted

技术标签:

【中文标题】使用 cin::fail() 从标准输入进行无限循环读取【英文标题】:Infinite loop reading from stdin using cin::fail() 【发布时间】:2013-12-18 12:42:23 【问题描述】:

我正在努力使用矢量 push_back 函数。 目标是拥有一个推送 n 个元素的函数,直到您决定停止。 所以我对“停止”的想法是 cin.fail()。

错误的功能是

void pushbackVector(vector<double> &data)

    double input;
    cin >> input;

    for (int i = 0; i < 100; i++)
    
        if (cin.fail())
        
            cout << "Ending input.\n";
            return;
        
        else
        
            data.push_back(input);
        
    

问题是当我尝试使用它时,我进入了一个无限循环。

我还没有按 ASC 顺序对第一个向量进行排序,按 DESC 顺序对第二个向量进行排序,并将第一个和第二个向量连接到第三个向量中。但是,我有信心自己可以解决这个问题。 反正整个代码....

#include<iostream>
#include<vector>
#include<algorithm>
#include<cctype>

using namespace std;

// function prototypes
void menu();
void printVector(const vector<double> &data);
void pushbackVector(vector<double> &data);
void sortVector (vector<double> &data);

int main()

    menu();

    vector<double> row1;
    vector<double> row2;

    /* not yet used
    vector<double> row3;
    */

    int input;
    cin >> input;

    bool exit = 0;

    while (!exit)
    
        switch (input)
        
            case 1:
                pushbackVector(row1);
                break;

            case 2:
                pushbackVector(row2);
                break;

            case 3:
                printVector(row1);
                break;

            case 4:
                printVector(row2);
                break;

            case 5:
                cout << "Printing out the contents of row 1\n";
                printVector(row1);
                cout << "Printing out the contents of row 2\n";
                printVector(row2);
                cout << "Printing out the contents of row 3\n";
                // printVector(row3);
                break;

            case 6:
                cout << "Exitting\n";
                exit = 1;
                break;

            default:
                cout << "Invalid choice\n";
        
    


    return 0;


void menu()

    cout << "Choose an option\n";
    cout << "1) Enter first vector\n";
    cout << "2) Enter second vector\n";
    cout << "3) Print out the first vector\n";
    cout << "4) Print out the second vector\n";
    cout << "5) Print out all three vectoros\n";
    cout << "6) Exitting the program\n";


void printVector(const vector<double> &data)

    for(int i = 0; i < data.size(); i++)
    
        cout << data[i] << ", ";
    
    cout << "\n";


void pushbackVector(vector<double> &data)

    double input;
    cin >> input;

    for (int i = 0; i < 100; i++)
    
        if (cin.fail())
        
            cout << "Ending input.\n";
            return;
        
        else
        
            data.push_back(input);
        
    



void sortVector (vector<double> &data)

    cout << "Sorting your vector \n";
    sort(data.begin(), data.end());

【问题讨论】:

我严重怀疑你是否通过 for 循环进入了无限循环。 修正了误导性标题。这真的和push_back无关。 【参考方案1】:

你只读取一次,将读取移到循环内:

void pushbackVector(vector<double> &data)

    double input;
    // cin >> input;   --------------
                                    //
    for (int i = 0; i < 100; i++)   //
                                   //
        cin >> input;   // <---------

        if (cin.fail())
        
            cout << "Ending input.\n";
            return;
        
        else
        
            data.push_back(input);
        
    

这将确保您真正获得输入。现在,如果您不打算输入 100 个值,则需要以某种方式通知流。这是通过在其中插入“EOF 字符”来完成的。在 Windows 上按 CTRL+Z 或在 unix 终端上按 CTRL+D。

当从流中读取它时,它会进入fail(和eof)状态,除非您在适当的时候通过调用cin.clear() 清除错误标志,否则它将保持这种状态。

你在 main.js 中也犯了同样的错误。您在while 循环之前只读取一次,因此input 保留您最初输入的值并继续输入相同的选择。我认为这就是你所说的无限循环。要修复它,请将 read 语句移到 switch 之前。

希望对您有所帮助。


另外,这就是我编写函数的方式:

double input;
for (int i = 0; (cin >> input) && i < 100; ++i) 
     data.push_back(input);

cout << "Ending input.\n";

流可用于布尔表达式 - 它们转换为 !fail() 的结果 - 这是控制循环的一种方便且惯用的方式。

【讨论】:

仍然进入无限循环>. @AntonAntonov 你要输入 100 个值吗? 我看不到 pushbackVector 出现无限循环的任何可能性。我的意思是它最多可以接受 100 个值,仅此而已。如果存在无限循环,则在代码中的其他位置。 无限循环肯定在main中。你也需要在你的循环里面做你的cin。 @drescherjm 是的,我确实说过。【参考方案2】:

无限循环是因为你正在阅读:

cin >> input;

一次,然后进入一个while 循环(在您的main 中),该循环将一直持续下去(除非输入最初等于6)。

变化:

cin >> input;

bool exit = 0;

while (!exit)

    // ...

到:

bool exit = 0;

while (!exit)

    cin >> input;
    // ...

根据您的逻辑,pushbackVector 函数中也会发生同样的情况:

double input;
cin >> input;

for (int i = 0; i < 100; i++)

    // ...

您可能希望将其更改为:

double input;

for (int i = 0; i < 100; i++)

    cin >> input;
    // ...

【讨论】:

【参考方案3】:

改为这样做:

void pushbackVector(vector<double> &data)

    double input;

    while (cin >> input) //will return true when there's valid input, otherwise false
    
        if (input == -1)
        
            cout << "Ending input.\n";
            return;
        
        else
        
            data.push_back(input);
        
    

这将读取输入,直到您输入 -1 或输入无效输入。

我认为依赖cin.fail() 并不是一个好主意。链接中解释了use fail() 的正确方法。这不是你所期望的。

【讨论】:

你为什么要检查-1【参考方案4】:

抛开错位的读数,如果您输入了不应该输入的内容,则需要清除输入。

先加入te的块

cin.clear(); 
cin.ignore( numeric_limits<streamsize>::max(), '\n' );

【讨论】:

【参考方案5】:

我会这样写函数

void pushbackVector( std::vector<double> &data )

    cin.clear(); 
    cin.ignore( std::numeric_limits<streamsize>::max(), '\n' );

    data.insert( data.end(), std::istream_iterator<double>( std::cin ), std::istream_iterator<double>() ); 

【讨论】:

【参考方案6】:

我几天前就完成了,但我忘了发布我的答案。 谁知道我只能说如果cin失败,停止输入但不要结束程序,lol。

    #include<iostream>
    #include<vector>
    #include<algorithm> // for sort algorithms
    #include<iomanip>  // for setprecision

    using namespace std;

    // function prototypes
    void menu();
    void printVector(const vector<double> &data);
    void pushbackVector(vector<double> &data);
    void sortVector (vector<double> &data);

    int main()
    
        vector<double> row1;
        vector<double> row2;
        vector<double> row3;

        int input;
        bool exit = false;

        while(!exit)
        
            menu();
            cin >> input;

            switch (input)
            
                case 1:
                    cout << "Entering vector 1\n";
                    pushbackVector(row1);
                    sortVector(row1);

                    cout << "\n";
                    break;

                case 2:
                    cout << "Entering vector 2\n";
                    pushbackVector(row2);
                    sortVector(row2);
                    reverse(row2.begin(), row2.end());

                    cout << "\n";
                    break;

                case 3:
                    cout << "Printing out vector 1\n";
                    printVector(row1);

                    cout << "\n";
                    break;

                case 4:
                    cout << "Printing out vector 2\n";
                    printVector(row2);

                    cout << "\n";
                    break;

                case 5:
                    // reserve enough space for all of row1's and row2's elements
                    row3.reserve(row1.size() + row2.size());
                    // insert row1's elements at the end of row3
                    row3.insert(row3.end(), row1.begin(), row1.end());
                    // insert row2's elements at the end of row3
                    row3.insert(row3.end(), row2.begin(), row2.end());


                    cout << "Printing out the contents of vector 1\n";
                    printVector(row1);
                    cout << "Printing out the contents of vector 2\n";
                    printVector(row2);
                    cout << "Printing out the contents of vector 3\n";
                    printVector(row3);


                    cout << "\n";
                    break;

                case 6:
                    cout << "Exitting\n";
                    exit = true;
                    break;

                default:
                    cout << "Invalid choice\n";
            
        


        return 0;
    

    void menu()
    
        cout << "Choose an option\n";
        cout << "1) Enter first vector\n";
        cout << "2) Enter second vector\n";
        cout << "3) Print out the first vector\n";
        cout << "4) Print out the second vector\n";
        cout << "5) Print out all three vectoros\n";
        cout << "6) Exitting the program\n";
    


    void printVector(const vector<double> &data)
    
        for(int i = 0; i < data.size(); i++)
        
            cout << setprecision(4) << data[i] << " ";
        
        cout << "\n";
    

    void pushbackVector(vector<double> &data)
    
        double input;
        int numOfItems;
        cout << "How many items you want to add into vector?: ";
        cin >> numOfItems;

        for (int i = 0; i < numOfItems; i++)
        
            cin >> input;
            if (cin.fail())
            
                cout << "Ending input.\n";
                return;
            
            else
            
                data.push_back(input);
            
        
    

    void sortVector(vector<double> &data)
    
        cout << "Sorting your vector \n";
        sort(data.begin(), data.end());
    

【讨论】:

以上是关于使用 cin::fail() 从标准输入进行无限循环读取的主要内容,如果未能解决你的问题,请参考以下文章

cin.good(),cin.fail(),cin.clear()

C++ 中的 cin.fail() 和 !cin 有啥区别?

无限循环计算阶乘问题

cin>>的返回值与cin.fail()的返回值是完全同步的吗?

是否有任何函数可以从标准输入中获取无限的输入字符串

错误处理