【问题标题】:Infinite loop when using exceptions in c++11在c ++ 11中使用异常时的无限循环
【发布时间】:2018-07-16 09:19:09
【问题描述】:

我想创建一个 c++11 程序,它接受 10 个正整数并为用户提供总数。如果输入负数或字符,则应抛出异常,用户必须重新输入其值。

下面的程序适用于负数。但是,当我输入像“a”这样的字符时,程序进入了一个无限循环,我不知道为什么。

我们将不胜感激任何和所有的帮助

#include <iostream>

int main(){
    int array[10] = {0};
    int total = 0;

    for(int i =0; i < 10; i++){
        std::cout<<"Number "<< i+1 << ": " <<std::endl;
        std::cin >> array[i];
        try{       
            if(array[i] < 0 || std::cin.fail())
                throw(array[i]);
        }
        catch(int a){
            std::cout<< a <<" is not a positive number! "<<std::endl;
            i-=1; // to go back to the previous position in array
        }
    }
    for(int k = 0; k < 10; k++)
        total+=array[k];

    std::cout<<"Total: " <<total<<std::endl;
}

【问题讨论】:

  • 当你输入一个字符而不是数字时,会到达捕获线吗?
  • 是的,错误信息被打印出来,但它是一个无限循环。如果输入数字,程序将按预期运行。
  • C++ if(!cin) causes loop的可能重复
  • 程序在输入字母时进入无限循环,因为cin &gt;&gt; array[i]在遇到字母时停止,不会更改array[i],导致cin.fail()返回true,并离开下次循环读取流缓冲区中的字母。尝试将数据读取为std::string,解析该字符串以确定是否输入了整数值,并丢弃其他任何内容(如字母)。异常的使用与问题无关。另外:抛出异常是不必要的,因为你在抛出异常的函数中捕获异常。

标签: c++ c++11 g++ gnu


【解决方案1】:

如果输入无效,您需要做两件事:

  1. 清除流状态。这是使用clear 函数完成的。

  2. 从缓冲区中删除无效输入。这通常使用ignore 函数完成。


至于你的程序,这里不需要异常,只需使用无符号整数并检查状态即可:

unsigned int array[10] = { 0 };

...

if (!(std::cin >> array[i])
{
    std::cout << "Please input only non-negative integers.\n";

    // First clear the stream status
    std::cin.clear();

    // Then skip the bad input
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

    // Make sure the index isn't increased
    --i;
}

要使用类似于你现在所做的异常,解决方案几乎与上面完全相同:

unsigned int array[10] = { 0 };

...

if (!(std::cin >> array[i])
{
    throw i;
}
catch (int current_index)
{
    std::cout << "The input for number " << current_index + 1 << " was incorrect.\n";
    std::cout << "Please input only non-negative integers.\n";

    // First clear the stream status
    std::cin.clear();

    // Then skip the bad input
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

    // Make sure the index isn't increased
    --i;
}

【讨论】:

  • 谢谢,但这是一个关于异常的编程作业,必须使用异常来处理错误的输入。
  • @Noob_Programmer 那么我的回答应该仍然对你有所帮助。使用unsigned int,使用clear,使用ignore
  • 我试过你说的。不幸的是,似乎仍然是一个无限循环。无论如何感谢您的帮助。
  • @Noob_Programmer 然后用你的最新代码更新你的问题。 clear()ignore() 是答案的一部分,但显然你还有其他问题。
【解决方案2】:

在代码中使用以下行时不要忘记包含限制头文件:

std::cin.ignore(std::numeric_limits::max(), '\n');

因为这个头文件中定义了 numeric_limits 模板!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-09
    • 1970-01-01
    • 2018-02-06
    相关资源
    最近更新 更多