【问题标题】:Non-numerical input causes endless loop非数字输入导致无限循环
【发布时间】:2012-07-04 01:57:42
【问题描述】:

由于某种原因,如果用户输入了错误的数据类型,例如 'j' 或 '%',循环将停止请求输入,并不断地显示"Enter an integer >"。如何让程序处理错误的输入?为什么输入一个非数值会导致这种奇怪的行为?

#define SENTINEL 0;
int main(void) {
  int sum = 0; /* The sum of numbers already read */
  int current; /* The number just read */

  do {
    printf("\nEnter an integer > ");
    scanf("%d", &current);
    if (current > SENTINEL)
      sum = sum + current;
  } while (current > SENTINEL);
  printf("\nThe sum is %d\n", sum);
}

【问题讨论】:

  • scanf() 在第一个非数字字符处停止。它将该字符保留在缓冲区中。下一次循环时,角色仍然存在,scanf 停止。下一次循环时,角色仍然存在,scanf 停止。下一次循环... ...
  • 由于SENTINEL 宏的值,这段代码甚至不应该编译。可能你想要#define SENTINEL 0
  • 那只是一个错字。就像你在原始程序中写的那样,我在上面修复了它。

标签: c loops input do-while


【解决方案1】:

如果scanf() 找不到匹配的输入,current 变量将保持不变:检查scanf() 的返回值:

/* scanf() returns the number of assignments made.
   In this case, that should be 1. */
if (1 != scanf("%d", &current)) break;

如果您希望在输入无效后继续接受输入,则需要从 stdin 读取无效数据,因为它将保留,正如 cmets 中的 pmg 所指出的那样。一种可能的方法是使用格式说明符"%*s" 来读取输入但不执行分配:

if (1 != scanf("%d", &current))
{
    scanf("%*s");
}
else
{
}

【讨论】:

  • 那么为什么程序在下一次循环迭代中不等待用户输入呢?它似乎只是跳过了 scanf 步骤。
  • @RobAlejandroVolgman,输入未读,下次调用 scanf() 时仍然存在。
【解决方案2】:

一种方法是将输入读入字符串,然后将字符串转换为您想要的数据类型。

我的 C 有点生疏,但我记得使用 fgets() 读取字符串,然后使用 sscanf() 将字符串解析/“读取”到我感兴趣的变量中。

【讨论】:

    猜你喜欢
    • 2014-06-18
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    • 2020-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多