【问题标题】:Reading ASCII character causes an infinite loop读取 ASCII 字符会导致无限循环
【发布时间】:2021-09-10 10:01:08
【问题描述】:

如果您输入整数值,则循环工作正常,但如果您输入一些 ASCII 字符或float 类型值,程序将进入无限循环。这个问题有什么解决办法吗? 从技术上讲,charint 的一种类型,所以这应该不是问题。

#include <stdio.h>

int main(void)
{
  int num;

  scanf("%d",&num);
  while (num < 40)
  {
    printf("Number is small\n");
    scanf("%d",&num);
  }
  return 0;
}

【问题讨论】:

  • 需要查看scanf的返回值。
  • scanf 在非数字上停止,因此在读取用户的行时最好使用 fgets。
  • 暂时不用担心。严重地。有关理由,请参阅this answer

标签: c while-loop ascii


【解决方案1】:

函数scanf 将尝试从stdin 中读取一个十进制整数。它使用来自strtol的十进制整数的定义:

有效的整数值由以下部分组成:

  • (可选)加号或减号
  • (可选)前缀 (0) 表示八进制基数(仅当基数为 8 或​0​时适用)
  • (可选)前缀(0x 或 0X)表示十六进制基数(仅当基数为 16 或 ​0​时适用)
  • 数字序列

换句话说,scanf 将尝试解释stdin 上的字符序列作为十进制整数。它不会根据 ASCII 表进行字符到整数的转换。

你的问题的解决方法在于检查scanf的返回值,即:

成功分配的接收参数数(如果在分配第一个接收参数之前发生匹配失败,则可能为零),如果在分配第一个接收参数之前发生输入失败,则为 EOF。

所以,检查 scanf 是否没有返回 1。在这种情况下,它没有读取十进制整数,并且 num 没有被赋值并且不应该被使用。
在给定的程序中,如果num 从未被赋值,则它的值是不确定的。这可能是一个 scanf 反复尝试从 stdin 读取非整数,失败并将非整数留在 stdin 上。如果之前为 num 分配了一个值,那么在失败的 scanf 调用之后它仍将保持该值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    • 1970-01-01
    • 2016-05-01
    • 2011-08-23
    • 2011-11-16
    相关资源
    最近更新 更多