【问题标题】:how does scanf() check if the input is an integer or character?scanf() 如何检查输入是整数还是字符?
【发布时间】:2011-04-12 01:38:29
【问题描述】:

我想知道当字符本身只是一个数字时,当我们调用 scanf("%d",&var) 时,标准 C 库函数 scanf() 如何检查输入是整数还是字符? 我知道当它遇到非整数时,它会将其放回输入缓冲区并返回 -1,但它如何知道输入不是整数?

【问题讨论】:

    标签: c scanf


    【解决方案1】:

    您是正确的,因为每个字符实际上都表示为一个 8 位整数。解决方法很简单:查看那个数字,看看它是否在 48-57 范围内,即字符 '0' - '9' 的 SCII 代码范围。

    scanf()source code 的第 1315 行开始,我们可以看到这一点。不过,scanf() 实际上更复杂 - 它还查看多字节字符来确定数值。第 1740 行是魔法发生的地方,该字符实际上被转换为一个数字。最后,这可能是最有用的,strtol() 函数会循环执行该转换。

    【讨论】:

      【解决方案2】:

      输入总是一个字符串。如果scanf 需要一个整数(因为您将它传递给"%d"),它会尝试为您将字符串转换为整数。

      【讨论】:

      • 但无论我们输入什么,它都是一个全是数字的 ascii 值序列。不是吗?
      • 你的意思是,代表数字的 ASCII 值。 scanf 获取字符 '9',确定它代表一个数字,并将其转换为整数 9。
      • 是的,它应该这样做。键盘只会发送 ascii 字符。
      【解决方案3】:

      在 scanf 语句中,您提到 %d 仅保存整数,因此默认情况下它理解变量为整数

      【讨论】:

        【解决方案4】:

        基本上,scanf 函数会根据您传递的转换说明符匹配正则表达式。如果您指定%d,则告诉scanf 将输入与'0''9' 之间的一个或多个字符(可选以+- 字符开头)的正则表达式匹配。然后它将该字符序列转换为等效的整数值。

        一个非常简单的版本可能看起来像这样:

        while (isdigit(c = fgetc(stream))
          val = val * 10 + valueOf(c); 
        ungetc(c, stream);
        

        其中isdigit 是标准库函数,如果字符值表示十进制数字,则返回真(非零),valueOf 是映射表示整数的字符的用户定义函数('0' - '9') 到等效的整数值 (0 - 9)(我不知道有一个标准库函数对单个字符值执行此操作)。为什么不直接从c 中减去'0' 以获得等效的整数值?根据编码,不能保证所有十进制整数字符都会按顺序排列(All The World Is Not ASCII);最好将实际转换委托给知道当前编码的函数。

        【讨论】:

          【解决方案5】:

          它尝试从流的开头解析一个有效的十进制整数,实际上是可选的 + 或 - 然后是一个或多个数字的序列。

          【讨论】:

          • 您能解释一下它是如何解析的吗?例如。它如何区分 A 和值 65 因为 A 将作为 65 传递 - 它的 ascii 值?
          • 呃,很少尝试在这里读取十进制整数的 ASCII 表示。字母 A 不属于此类。
          【解决方案6】:

          它基本上使用如下循环:

          while (isdigit((ch=getchar()))
              // ...
          

          【讨论】:

            【解决方案7】:

            您误解了%d 格式说明符。它确实返回输入字符的ASCII值(你可以使用%c);它返回字符表示的整数。因此,在'9' 的输入字符上,%d 返回值 9,而不是 '9' 的 ASCII 值。

            (好吧,%d 实际上是查看一个字符序列,所以如果输入是 '9' 后跟 '0' 后跟 ' ',它将解释为 90)。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-05-05
              • 1970-01-01
              • 2020-03-20
              • 1970-01-01
              • 2011-09-01
              • 1970-01-01
              • 2015-06-09
              • 1970-01-01
              相关资源
              最近更新 更多