C while语句中的无穷循环

C while语句中的无穷循环,c,C,下面是我的代码片段 scanf("%d", &s); while(s!=1 && s!=2) { if(scanf("%d", &s) != 1) { show_warning(); //just print some info msg } } 其思想是仅当用户输入不同的值1,2且输入的值仅为整数时,才执行show_警告功能。 上面的代码在无限循环中跳跃。如何解决这个问题?为什么要使用while循环?您是否希望显示警告;一次,还

下面是我的代码片段

scanf("%d", &s);

while(s!=1 && s!=2) {
    if(scanf("%d", &s) != 1) {
        show_warning(); //just print some info msg
    }
}
其思想是仅当用户输入不同的值1,2且输入的值仅为整数时,才执行show_警告功能。
上面的代码在无限循环中跳跃。如何解决这个问题?

为什么要使用while循环?您是否希望显示警告;一次,还是多次?如果您只回答了一次,那么您只需要一个If语句。

当没有scanf成功时会发生什么?变量s保持不变,如果没有初始化,可能还有未定义的值。您应该设置它,或者更改while的条件


你真的应该学会在编译时启用警告和调试信息,例如Linux上的gcc-Wall-g,以及在Linux上使用调试器,例如gdb。问题是失败的输入操作不会从流中提取任何字符,你会不断地反复读取无效的输入,因此,您必须手动清空输入。例如:

char buf[1000];

// ...

if(scanf("%d", &s) != 1)
{
    puts("Error, try again: ");
    fgets(buf, 1000, stdin);
}
正如我在中所建议的,如果从一开始就使用FGET始终读取一行,然后再进行处理,则可以克服此问题


同样的原理在C++中也是如此:首先读取整行,这样输入流就可以继续,然后再处理这行,看看它是否有效。

是什么让你认为它一直循环到无穷远

只有当您没有输入数字,因为它没有读取令牌时,才会收到警告消息

将&&更改为| |虽然是确保它将无限运行的一种特定方式,因为您的循环将永远不会中断


当用户输入了数字而不是1或2时,您可能需要另一条消息来提示用户输入数据?

我假设您在输入非整数时遇到问题。这是因为scanf在缓冲区中留下了不匹配的字符,因此后续调用将看到相同的输入和循环


您需要做的是,如果scanf调用返回除1以外的任何数字,请执行以下操作:使用scanf%c和somechar在中读取该字符,以便打印该字符并告诉用户该字符不被接受。然后,将删除未接受的输入,因此下次调用scanf将为您提供下一个输入,而不是您在上一次迭代中看到的输入。

您能否向我们显示s的定义并显示警告?循环中的scanf将返回读取的令牌数,而不是输入的值。噢,我明白你的意思了:如果你不输入一个数字,而scanf失败了,那么你就进入了一个无限循环@现金牛:它认为OP已经意识到了这一点。这是一个经典的例子,说明了为什么scanf很难使用。如果使用fgets和sscanf,通常更容易控制错误处理并改进错误报告。否,&&是正确的。这是一个典型的问题,即无效输入没有被使用。或者当c=getchar!=EOF&c!='\n′;它消耗无限长的线条,而FGET只消耗不合理的长线条。@JonathanLeffler:对。我的首席执行官不如我想象的那么有说服力。。。也就是说,上面的构造也会循环并消耗尽可能多的信息,只是它会每隔这么多字符打印一次消息。我建议使用循环来代替fgets调用,因此您的循环将每隔这么多字符报告一个非常长的行,而另一种方法是每行报告一次。在大多数情况下,这种差异是无关紧要的。1 KiB足够大,人们在手动输入该行长度时会遇到问题。我的终端不允许缓冲那么多字符。理论上,这对于基于文件的输入很重要。实际上有一个微妙的区别:如果第1001个字符是1或2,那么我的构造会错误地成功,而你的构造会正确地消耗整行!