C ++无限循环

时间:2011-12-17 23:55:42

标签: c++

我正在学习C ++。

nav是整数

如果他/她输入无效值,我想要求用户输入有效值。

void main()
{
    printf("Type an integer : ");
    if(!scanf("%d", &nav))
    {
        system("cls");
        printf("Invalid ! \n");
        main();
    }
}

但输入第一个值后它会闪烁。它像重装屏幕一样闪烁。我认为这是无限循环。

我怎么能以正确的方式做到这一点?我想问用户的号码,直到它输入一个实数。

3 个答案:

答案 0 :(得分:3)

如果用户键入无效输入,scanf()将不会消耗它,并且您将永远偷看相同的违规输入字符。您需要先阅读用户输入的内容 - 我建议您使用std::getline() - 然后尝试使用strtol()sscanf()std::istringstream进行解析。请勿使用atoi(),因为它不会报告失败。

int nav;
{
    string line;
    while (getline(cin, line))
        if (istringstream(line) >> nav)
            break;
}

编辑:请参阅评论,了解上述逻辑的相当漂亮的演绎。我把它排除在答案之外是因为:a)我不想偷别人的想法,而且b)我不确定我是否会以这种方式呈现C ++的新手 - 不是一次性的,不是至少

P.S。:您无法在C ++中调用main()

答案 1 :(得分:1)

两件事。

Scanf在处理输入之前需要按下“enter”键,因此闪烁可能就是光标等待下一个键。

另外,从main调用main是相当不标准的。你应该看一下'while'循环。

答案 2 :(得分:0)

你的节目不是很好,但我会告诉你发生了什么。

在C / C ++中,当scanf无法从输入读取整数(%d)时,它不会读取任何内容。也就是说,无论阻止scanf读取int,都将保留在那里。在下一个scanf,相同的字符将导致错误。

让我举一个例子来证明。想象一下,你正在从这个输入中读取许多整数:

12 13 Shahbaz 15

现在,如果您使用scanf致电%d,则会看到12,输入内容为:

 13 Shahbaz 15

接下来,您使用scanf致电%d,然后阅读13。现在输入将是:

 Shahbaz 15

再次,您使用scanf致电%d。这里,输入以S(在空白之后)开始,使scanf返回失败,因为它无法读取整数。输入保持不变(可能保存为空白)。也就是说,输入将是:

 Shahbaz 15

正如您所看到的,使用%d读取输入将给出完全相同的错误,并且您陷入了无限循环。

要解决这个问题,你有很多选择。这在很大程度上取决于您希望如何处理这种情况,但有两种方法是在打印%c后立即读取字符(带%s)或字符串(带printf("Invalid\n")

第一种方法适合处理这样的输入:

12 13 q14 15

其中q是一个需要忽略的错误。第二种方法适合处理这样的输入:

12 13 Shahbaz 15

无效数据是有意义的单词,但您只想忽略它们。

如果我想使用scanf,那么会写它的方式是:

int main()   // always write int main
{
    int nav;
    printf("Type an integer: ");
    while (scanf("%d", &nav) != 1)   // scanf returns number of successful %'s read
    {
        printf("Invalid number. Try again: ");
        scanf("%*s");                // read a %s but ignore it
    }
    // The rest of the program, using nav
    return 0;
}