【问题标题】:C++ input validation while loop not terminating循环未终止时的 C++ 输入验证
【发布时间】:2017-10-13 19:20:02
【问题描述】:

我是 C++ 计算机科学入门课程的学生,这是我第一次在这里发帖。我们刚刚了解了 while 循环,虽然分配不需要它,但我正在尝试对此分配进行输入验证。该程序旨在读取一个数字列表并找出该列表中第一个和最后一个 8 的位置。所以如果我有四个数字(1、8、42、8)的列表,那么前8位和后8位分别是2和4。集合的大小由用户决定。

我试图创建一个 while 循环来测试以确保用户输入的内容实际上是一个数字,但是当我尝试输入类似“.”的内容时或“a”循环无限地进行并且不会终止。我找不到我的错误,据我所知,我使用的语法与教科书中的语法完全相同。有人可以告诉我我的 while 循环有什么问题吗?

int numbers,            //How large the set will be
    num,                //What the user enters for each number
    first8position = 0, //The first position in the set that has an 8
    last8position = 0;  //The last position in the set that has an 8

//Prompt the user to get set size
cout << "How many numbers will be entered?  ";
cin >> numbers;

//Loop to get all the numbers of the set and figure out
//which position the first and last 8 are in
for (int position = 1; position <= numbers; position++)
{
    cout << "Enter num:  ";
    cin >> num;

    //If num isn't a digit, prompt the user to enter a digit
    while (!isdigit(num))
    {
        cout << "Please enter a decimal number:  ";
        cin >> num;
    }

    //If num is 8, and first8position still isn't filled,
    //set first8position to the current position.
    //Otherwise, set last8position to the current position.
    if (num == 8)
    {
        if (first8position == 0)
            first8position = position;
        else
            last8position = position;
    }


}

//If the set had an 8, print what its position was
if (first8position != 0)
    cout << "The first 8 was in position " << first8position << endl;

//If there was more than one 8, print the last 8 position.
//Otherwise, the first and last 8 position are the same.
if (last8position != 0)
    cout << "The last 8 was in position " << last8position << endl;
else
    cout << "The last 8 was in position " << first8position << endl;

//If there were no 8s, say so.
if (first8position == 0)
    cout << "Sorry, no eights were entered.";

return 0;

}

【问题讨论】:

标签: c++ validation


【解决方案1】:

有两个问题导致你的死循环:

首先,使用cin &gt;&gt; num,您尝试读入一个整数值。如果用户输入诸如a. 之类的内容,它们不能是整数值的开头,则不会读入任何内容,a. 仍保留在输入缓冲区中;因此,每个后续的cin &gt;&gt; num 都会立即失败(不给用户输入内容的机会,因为a. 仍在输入缓冲区中并将保留在那里)。因此,在这种情况下,您将不得不使用来自 cin 的这些字符,例如通过使用cin.ignore,您将不得不重置failbit,这也是在这种情况下设置的。

其次,注意isdigit(int c) 检查ASCIIc 是否为数字,即c &gt;= 48 &amp;&amp; c &lt;= 57。因此,您的检查 isdigit(num) 将失败,直到用户输入介于 4857 之间的数字。

请参阅以下代码,演示如何处理输入失败。希望对您有所帮助。

int main() {

    int num;
    cin >> num;
    while (!cin.eof() && cin.fail()) {  // failure when extracting an integral value?
        cout << "not an integral value." << endl;

        // clear failbit
        cin.clear();

        // remove characters that are still in the input buffer (until next end of line)
        cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

        // next try to read in an integer
        cin >> num;
    }
    if (!cin.eof()) {
        cout << "juu:" << num << endl;
    }
}

【讨论】:

  • 您可以阅读下一个num 并同时使用while(!(cin &gt;&gt; num)) 检查失败。
  • @WorldSEnder:它必须是while (! (cin &gt;&gt; num)),但是当到达 EOF 时,您可能会陷入无限循环。这可以通过专门测试failbit来避免。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-10
  • 1970-01-01
  • 2019-06-15
  • 2020-12-25
  • 2011-11-02
  • 2021-05-13
  • 2014-10-11
相关资源
最近更新 更多