简体   繁体   English

在scanf获得意外数据后,C程序无限循环

[英]C program loops infinitely after scanf gets unexpected data

I have a program where I want the input integer to be between 2 and 64 inclusive, so I put scanf inside a do { ... } while loop. 我有一个程序,我希望输入整数在2到64之间,所以我把scanf放在do { ... } while循环中。 Here's the code I initially tested: 这是我最初测试的代码:

int initialBase;

do {
  printf("Initial base: ");
  scanf("%i", &initialBase);
} while (initialBase < 2 || initialBase > 64);

The problem is whenever the input is not a valid integer, it just outputs the printf statement indefinitely and no longer prompts for user input, instantly flooding the console. 问题是每当输入不是有效整数时,它只是无限地输出printf语句而不再提示用户输入,立即充斥控制台。 Why is that happening and what's a better way of reading input that satisfies the conditions I want? 为什么会发生这种情况,什么是更好的阅读输入方式,满足我想要的条件?

When scanf() fails, the argument is not automatically initialized, and uninitialized values could be any value, so it might be less than 2 or greater than 64 no one knows. scanf()失败时,参数不会自动初始化,未初始化的值可以是任何值,因此它可能小于2或大于64没有人知道。

Try this 试试这个

int initialBase;

/* some default value would be good. */
initialBase = 2;
do {
  printf("Initial base: ");
  if (scanf("%i", &initialBase) != 1)
      break;
} while ((initialBase < 2) || (initialBase > 64));

the check will break out of the loop if you input something that is not a number, the initialiazation of initialBase is just a good habit which in your case could have prevented the behavior you describe, but in this case it's there to prevent accessing an uninitialized value after the while loop. 该检查将退出循环,如果你输入的东西是不是一个数字,的initialiazation initialBase只是它在你的情况可能会阻止您的行为描述一个好习惯,但在这种情况下,它的存在,以防止访问未初始化while循环后的值。

The reason the loop didn't stop, was because scanf() leaves some characters in the input stream when they are not matched, and calling scanf() again while those characters are still there will make scanf() keep waiting for valid input, but returning immediatly with the currently invalid input that is in the stream, if you want to keep reading, try reading characters from the stream until a '\\n' is found, this way 循环没有停止的原因是因为scanf()在它们不匹配时在输入流中留下了一些字符,并且当这些字符仍然存在时再次调用scanf()将使scanf()继续等待有效输入,但是立即返回流中当前无效的输入,如果你想继续阅读,尝试从流中读取字符,直到找到'\\n' ,这样

int initialBase;

initialBase = 0;
do {
    printf("Initial base: ");
    if (scanf("%i", &initialBase) != 1)
    {
        while (fgetc(stdin) != '\n');
        continue;
    }
} while ((initialBase < 2) || (initialBase > 64));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM