为什么这个while循环输出同样的东西,无论你输入什么?

时间:2017-02-10 02:13:07

标签: c++ vector while-loop

我有一个程序可以做三件事。询问您有多少变量,要求您输入每个变量,然后将其存储在矢量中。我已经放了一些代码来检查你的输入是否正确,如果不是,则重新循环代码,询问你的变量。我遇到的问题是,当你在第二个变量周围输入任何内容时,它会要求你无限再试。

例如,如果我将这些值输入到输入中:

Variable amount: 5
Please input variable 1: 8
Please input variable 2: 8

 ERROR, PLEASE ENTER ONLY VALID SYMBOLS
---------------------

Please input variable 2:

无论你键入什么,它都会一遍又一遍地输出ERROR, PLEASE ENTER ONLY VALID SYMBOLS。代码如下,如果您对此问题有更好的名称,请告诉我。 (我不确定该怎么称呼它)

#include <iostream>
#include <cmath>
#include <string>
#include <algorithm>
#include <vector>
#include <sstream>

using namespace std;

int inputErrorMessage()
{
    cout << "\n ERROR, PLEASE ENTER ONLY VALID SYMBOLS \n";
    cout << "--------------------- \n";

    return 0;
}

int main()
{
    // Declare the variables, vectors, etc.
    int varNum = 1;
    int totVar = 0;
    int choice = 0;
    vector<int> userNums;
    double input = 0;
    string checktotVar = "";
    string checkInput = "";
    string sym = "";
    bool valid = false;
    stringstream sstotVar;
    stringstream ssinput;

    if (choice != 6) {

        while (!valid) {

            valid = true;

            // Ask user for how many variables they want then record it
            cout << "Variable amount: ";
            getline(cin, checktotVar);
            sstotVar << checktotVar;
            sstotVar >> totVar;

            if (sstotVar.fail() || totVar <= 0) {
                inputErrorMessage();
                valid = false;
                sstotVar.clear();
                sstotVar.ignore();
            }
        }

        valid = false;

        while (!valid) {

            valid = true;

            // Ask the user for each variable, then record it into the array
            for (int i = 0; i < totVar; ++i) {
                cout << "Please input variable " << varNum << ": ";
                getline(cin, checkInput);
                ssinput << checkInput;
                ssinput >> input;

                if (ssinput.fail()) {
                    inputErrorMessage();
                    valid = false;
                    ssinput.clear();
                    ssinput.ignore();
                }
                if (valid == true) {
                    userNums.push_back(input);
                    varNum++;
                }
            }
        }
    }
}

3 个答案:

答案 0 :(得分:1)

以下是此代码的问题。

在这部分:

if (valid == true) {
    userNums.push_back(input);
    varNum++;
}

你忘了添加一个ssinput.clear()。这将重置流状态(清除错误标志),否则您将无法再次使用它。这就是为什么它停止在第二个输入工作。

此外,即使这样可行,您也可以将声明为double的变量推回到int的向量中。如果这是为了存储双变量而不是截断它们并将它们存储为整数,那么这必然会引起问题。

答案 1 :(得分:1)

ssinput >> input;

ssinput中的一个内容读取到流的末尾,同时保持读取有效。下一次

ssinput << checkInput;

无法写入流,因为流命中了流的末尾。这意味着读取也失败了

if (ssinput.fail()) {

进入程序清除错误的if正文

ssinput.clear();

然后立即用

读取流的结尾
ssinput.ignore();

再次导致错误。

最快的解决方案:

重新创建

stringstream ssinput;

每次循环迭代。所以

stringstream sstotVar;
//stringstream ssinput; gone from here

    getline(cin, checkInput);
    stringstream ssinput(checkInput); // and now tighter scope recreated each loop.
    ssinput >> input;

同样通过保持流不被排空,它可以变得非常非常大。

您还可以简化您的逻辑

while (!valid) {

通过将读取验证移入其自己的函数来消除一些重复的代码

int getMeANumber(const std::string & message, int min)

循环,直到获得一个数字,然后返回该数字。例如:

int getMeANumber(const std::string & message, int min)
{
    while (true)
    {
        cout << message;
        string checktotVar;
        getline(cin, checktotVar);
        stringstream sstotVar(checktotVar);
        int totVar;
        sstotVar >> totVar;

        if (!sstotVar || totVar <= min)
        {
            inputErrorMessage();
        }
        else
        {
            return totVar;
        }
    }
}

现在main就是这个非常小的小事。

int main()
{
    int choice = 0;
    vector<int> userNums;

    if (choice != 6)
    {
        int totVar = getMeANumber("Variable amount: ", 0);
        for (int i = 0; i < totVar; ++i)
        {
            stringstream varname;
            varname << "Please input variable " << i+1 << ": ";
            userNums.push_back(getMeANumber(varname.str(), numeric_limits<int>::min())); 
            // numeric_limits<int>::min requires #include <limits>
        }
    }
}

答案 2 :(得分:1)

应该是:

#include <iostream>
#include <cmath>
#include <string>
#include <algorithm>
#include <vector>
#include <sstream>

using namespace std;

int inputErrorMessage()
{
    cout << "\n ERROR, PLEASE ENTER ONLY VALID SYMBOLS \n";
    cout << "--------------------- \n";

    return 0;
}

int main()
{
    // Declare the variables, vectors, etc.
    int varNum = 1;
    int totVar = 0;
    int choice = 0;
    vector<int> userNums;
    double input = 0;
    string checktotVar = "";
    string checkInput = "";
    string sym = "";
    bool valid = false;
    stringstream sstotVar;
    stringstream ssinput;

    if (choice != 6) {

        while (!valid) {

            valid = true;

            // Ask user for how many variables they want then record it
            cout << "Variable amount: ";
            getline(cin, checktotVar);
            sstotVar << checktotVar;
            sstotVar >> totVar;

            if (sstotVar.fail() || totVar <= 0) {
                inputErrorMessage();
                valid = false;
                sstotVar.clear();
                sstotVar.ignore();
            }
        }

        valid = false;

        while (!valid) {

            valid = true;

            // Ask the user for each variable, then record it into the array
            for (int i = 0; i < totVar; ++i) {
                cout << "Please input variable " << varNum << ": ";
                getline(cin, checkInput);
                ssinput << checkInput;
                ssinput >> input;

                if (ssinput.fail()) {
                    inputErrorMessage();
                    valid = false;

                }
                if (valid == true) {
                    userNums.push_back(input);
                    varNum++;
                }

                ssinput.clear();
            }
        }
    }
}

编辑:您需要在循环的每次迭代中清除字符串流,否则当您从用户获取下一个输入时,您不会写入空流,这是导致.fail()方法在循环的第一次迭代后返回true。