在c ++ 11中使用异常时的无限循环

Posted

技术标签:

【中文标题】在c ++ 11中使用异常时的无限循环【英文标题】:Infinite loop when using exceptions in 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,解析该字符串以确定是否输入了整数值,并丢弃其他任何内容(如字母)。异常的使用与问题无关。另外:抛出异常是不必要的,因为你在抛出异常的函数中捕获异常。 【参考方案1】:

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

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

    从缓冲区中删除无效输入。这通常使用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 模板!

【讨论】:

以上是关于在c ++ 11中使用异常时的无限循环的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring boot 中使用 post 方法保存多个实体时的无限循环

为啥我的代码在执行时的初始嵌套 for 循环中进入无限循环?

Spring Batch SkipPolicy在处理异常时陷入无限循环

对数组使用 setState 时的无限循环

在 componentWillReceiveProps 中调度时的无限循环

在while循环中使用execvp和fork时的无限循环