繁体   English   中英

当您对小数使用 scanf() 但输入字母时会发生什么

[英]What happens when you use scanf() for a decimal, but enter in a letter

我有从用户那里获取一个数字并将其输出的代码。 我很好奇的是,当输入一个字母时,它会输出一个非常高的数字,大约 32765,有时更多,有时更少。 似乎只是随机选择一个数字。 我的代码如下。

#include <stdio.h>

int main(void) {
  int num;
  scanf("%d", &num);
  printf("%d", num);
  return 0;
}

为什么会发生这种情况,它是可以预测的吗?

检查scanf()的返回值。

返回值

成功时,这些函数( scanf()系列)返回成功匹配和分配的输入项数; 在早期匹配失败的情况下,这可能比规定的要少,甚至为零。

因此,您看到的随机值只是在scanf()调用之前存在于num中的垃圾值。

试验不同的输入组合(有效/无效):

#include <stdio.h>

int main (void) {
    int num;
    char ch;
    char str[24] = ">?Junk Data?><<>?<>?";
    float fnum;

    printf ("\nNum: %d\nStr: %s\nFloat: %f\nChar: [%c]\n", num, str, fnum, ch);

    int status = scanf ("%d %23s %f %c", &num, str, &fnum, &ch);
    printf ("\nStatus %d Inputs read\n", status);
    printf ("\nNum: %d\nStr: %s\nFloat: %f\nChar: [%c]\n", num, str, fnum, ch);

    // to check input buffer is intact
    // input just "TestingInputBuffer"
    status = scanf ("%23s", str); //returns to read where it left-off from last call
    printf ("\nStatus: %d\nString: %s\n", status, str);

    return 0;
}

当您调用scanf("%d", &num)时,它会从标准输入中读取字节:

  1. 任何空白字符都将被忽略。 这包括空格、制表符、换行符和一些不太常见的字符
  2. 如果字节是一个符号,它会被消耗并被记住。
  3. 然后数字被消耗并转换为一个值。
  4. 第一个非数字字节被推回标准输入,如果前面有负号,则该值可能取反,作为int存储到下一个参数指向的位置,该参数必须是int *

如果第 3 阶段读取的第一个字节不是数字,则将其推回并且转换失败, scanf()返回当前成功转换的数量,在您的情况下为0

如果在可以执行第一次转换之前遇到 end if file,则返回EOF

因此,如果用户键入Ascanf()返回0并且num不变。 由于num未初始化,因此将其值传递给printf以进行%d转换具有未定义的行为。 在你的例子中, num恰好有一个大约 32765的值,它得到 output,但这种行为确实是不可预测的:任何事情都可能发生,包括程序终止。 您应该始终测试scanf()的返回值以检测无效或丢失的输入并避免未定义的行为。

这是修改后的版本:

#include <stdio.h>

int main(void) {
    int num;
    if (scanf("%d", &num) == 1) {
        printf("%d\n", num);
        return 0;
    } else {
        fprintf(stderr, "invalid input\n");
        return 1;
    }
}

暂无
暂无

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

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