如何成功清除流?

时间:2018-03-02 17:10:38

标签: c++ c++11

根据希腊数字命理学,我正在编写一个需要找到丰富,缺陷和完美数字的程序。这里代表的问题是确保只插入自然数;更具体地说,确保没有插入字母。 我尝试检查流是否已经打破"如果是,则打印相应的消息。它有效,但只有一次,我无法弄清楚原因。 这是代码。

 #include <iostream>
 int main ()
{
double n(0);
int sum(0);
int i(0);

std::cout << "Enter a natural number or 0 for exit: ";
std::cin >> n;

int n1 = n;
do {
    for(i = 1; i < n1; i++) {
        if(n1 % i == 0) {
            sum+=i;
        }
    }
    if(!std::cin) {
        std::cout << "Not a natural number!" << std::endl;
        std::cout << "Enter a natural number or 0 for exit: ";
    }
    else if(n != int(n)) {
        std::cout << "Not a natural number!" << std::endl;
        std::cout << "Enter a natural number or 0 for exit: ";
    }
    else if(n1 < 0) {
        std::cout << "Not a natural number!" << std::endl;
        std::cout << "Enter a natural number or 0 for exit: ";
    }
    else if(suma < n1) {
        std::cout << "Number " << n << " is deficient!" << std::endl;
        std::cout << "Enter a natural number or 0 for exit: ";
    }
    else if(suma > n1) {
        std::cout << "Number " << n << " is abudant!" << std::endl;
        std::cout << "Enter a natural number or 0 for exit: ";
    }
    else if(suma == n1) {
        std::cout << "Number " << n << " is perfect!" << std::endl;
        std::cout << "Enter a natural number or 0 for exit: ";
    }
    suma = 0;
    std::cin.clear();
    std::cin.ignore(1000, '\n');
    std::cin >> n;
    n1 = int(n);
} while(n != 0);
std::cout << "Goodbye!";

return 0;
}

2 个答案:

答案 0 :(得分:1)

这个问题似乎是一个逻辑问题。您提示重新输入n,然后

std::cin.clear();
std::cin.ignore(1000, '\n');
std::cin >> n;

这不会“恢复”流,这将丢弃'n'的用户输入,让您陷入困境。看起来您需要重新排序输入并循环以在每次迭代时处理输入一次。类似于以下内容:

#include <iostream>

int main (void) {

    double n(0);

    do {
        int sum(0);
        int i(0);

        std::cout << "Enter a natural number or 0 for exit: ";
        std::cin >> n;
        int n1 = n;

        for(i = 1; i < n1; i++)
            if(n1 % i == 0)
                sum+=i;

        if(n != int(n))
            std::cout << "Not a natural number!" << std::endl;
        else if(n1 < 0)
            std::cout << "Not a natural number!" << std::endl;
        else if(sum < n1)
            std::cout << "Number " << n << " is deficient!" << std::endl;
        else if(sum > n1)
            std::cout << "Number " << n << " is abudant!" << std::endl;
        else if(sum == n1)
            std::cout << "Number " << n << " is perfect!" << std::endl;

        sum = 0;

    } while(n != 0);

    std::cout << "Goodbye!\n";

    return 0;
}

.ignore.clear都不是必需的。数字转换会忽略前导空格,而.clear只会在流上设置'goodbit',这会清除所有错误标记。 (见std::basic_ios::clear)也没有必要检查if (!std::cin)。它没有伤害,它只是你的代码多余。

示例使用/输出

$ ./bin/inputnumber
Enter a natural number or 0 for exit: 128
Number 128 is deficient!
Enter a natural number or 0 for exit: 30
Number 30 is abudant!
Enter a natural number or 0 for exit: 37
Number 37 is deficient!
Enter a natural number or 0 for exit: 2
Number 2 is deficient!
Enter a natural number or 0 for exit: 1
Number 1 is deficient!
Enter a natural number or 0 for exit: 10
Number 10 is deficient!
Enter a natural number or 0 for exit: 12
Number 12 is abudant!
Enter a natural number or 0 for exit: 0
Number 0 is perfect!
Goodbye!

我不是100%明确你的目标,所以如果我误解了,请发表评论,我很乐意进一步提供帮助。

让您的输入放弃非数字

Rose,在评论中的讨论之后,如果出现输入错误(例如猫踩到键盘导致n1,则显示您的问题是0被分配";sdkfgj" 1}}正在输入)。这也是可以处理的,并且您在正确的轨道上查看.clear.ignore。至于你如何将它们放在一起有一些逻辑。

当遇到“如何确保用户只输入'X'?”的问题时,通常的方法是不断循环,直到用户输入满足您为接受输入设置的条件。在这里,您需要输入数值。因此,方法是循环,提示输入,然后在用户输入值后检查流状态。如果流出错,则需要.clear()错误,然后.ignore(..., ...)直至'\n'。 (您可以使用<limits>中的值来禁用字符计数检查并丢弃可能存在的任意数量的字符)

这留下了一个小问题。您在循环中循环输入以开始。如果用户输入0表示此处要退出,则必须中断两个循环才能转到"Goodbye!\n";。虽然您可以设置标志等,但低goto仍然是跳出嵌套循环的标准且有效的方法。

完全放弃,现在对你的问题有了更多了解,你可以做类似以下的事情:

#include <iostream>
#include <limits>

int main (void) {

    double n(0);

    do {
        int sum(0), n1(0);

        while (n1 == 0) {
            std::cout << "Enter a natural number or 0 for exit: ";
            std::cin >> n;
            if (!std::cin) {
                std::cin.clear();
                std::cin.ignore(std::numeric_limits<std::streamsize>::max(),
                                '\n');
            }
            else if (n == 0)
                goto alldone;
            else
                n1 = n;
        }

        for(int i = 1; i < n1; i++)
            if (n1 % i == 0)
                sum += i;

        if(n != int(n))
            std::cout << "Not a natural number!" << std::endl;
        else if(n1 < 0)
            std::cout << "Not a natural number!" << std::endl;
        else if(sum < n1)
            std::cout << "Number " << n << " is deficient!" << std::endl;
        else if(sum > n1)
            std::cout << "Number " << n << " is abudant!" << std::endl;
        else if(n1 && sum == n1)
            std::cout << "Number " << n << " is perfect!" << std::endl;

        sum = 0;

    } while(n != 0);

    alldone:;
    std::cout << "Goodbye!\n";

    return 0;
}

示例使用/输出

$ ./bin/inputnumber
Enter a natural number or 0 for exit: apples
Enter a natural number or 0 for exit: banannas
Enter a natural number or 0 for exit: 128
Number 128 is deficient!
Enter a natural number or 0 for exit: 96
Number 96 is abudant!
Enter a natural number or 0 for exit: foo
Enter a natural number or 0 for exit: 2
Number 2 is deficient!
Enter a natural number or 0 for exit: 0
Goodbye!

让我知道这是否是给你问题的领域。

答案 1 :(得分:0)

所以唯一的问题是将0分配给n1。当流&#34;被破坏&#34;,即它接收到与变量类型不对应的输入时,它将进入未定义状态,必须用{{1}清除}和.clear,它再次使其挂起.ignore值,从而导致循环结束。 我的解决方案可能是最原始的解决方案。只需为0分配一个随机整数值,并关闭案例。它不会影响其他n1,因为只会执行第一个,它也会阻止循环中断。 所以就:      if