【问题标题】:Can scanf() store values?scanf() 可以存储值吗?
【发布时间】:2013-08-21 18:57:07
【问题描述】:

您好,我现在正在学习 C 语言,但在练习我阅读的书时遇到了一点问题。我的代码是这样的:

#include<stdio.h>
int main()
{
  unsigned char one=0;
  unsigned char two=0;
  printf("Quantity 1 = ");
  scanf("%d",&one);
  printf("Quantity 2 = ");
  scanf("%d",&two);
  printf("The value is %d",one);
  return 0;
}

为什么当我试图查看one 的值时,会出现初始值而不是scanf 之后的值?

【问题讨论】:

  • 欢迎来到 SO。很好的例子展示了你的问题。
  • 正如下面@Shade 给出的链接,如果你想使用unsigned char 作为变量类型,你可以使用%c%hhu 格式说明符
  • 这里的根本原因与When using and int to read character, why is the value 4096 + ascii 中解决的问题相同。 scanf 可以存储值,但由于 unsigned charint 的大小不同(%d 所期望的),scanf 接收的值存储在 printf 所期望的位置。另见scanf and keeping char as an integer
  • @nishant fscanf() 长度修饰符:C11 7.21.6.2 11 "hh 指定后面的 d、i、o、u、x、X 或 n 转换说明符适用于类型为指针的参数为有符号字符或无符号字符。” fprintf() 类似。我希望可以减少疑虑。
  • @nishant:对于unsigned char,如果您将unsigned char 视为一个小整数,请使用%hhu,因此"42" 为您提供(unsigned char(42)。 (仅供参考,在大多数英语世界中,“怀疑”不是“问题”的同义词;“怀疑”这个词意味着不相信。)

标签: c scanf


【解决方案1】:

您需要将int 类型与%d 说明符结合使用,并将char%c 说明符结合使用。 %u 带有无符号整数。

#include<stdio.h>
int main()
{
    unsigned int one=0; unsigned int two=0;
    printf("Quantity 1 = ");scanf("%u",&one);
    printf("Quantity 2 = ");scanf("%u",&two);
    printf("The value is %u",one);
    return 0;
}

基本上,scanf 将尝试从输入中读取整数,并尝试将其存储在不够大的内存位置中,因此您将有未定义的行为。

你可以找到很好的参考here

但是,如果您尝试使用字符作为输入类型,您可能想问自己为什么没有机会输入第二个数量(如果您输入 4 并按回车键)。这是因为第二个scanf 会将输入键读取为字符。此外,如果您尝试键入 21(对于 21 岁),它将用 2 填充第一个值,然后用 1 填充第二个值(好吧,用它们的 ASCII 值)。

所以,要小心 - 确保始终为变量选择正确的类型。

【讨论】:

  • 在处理无符号整数时使用%u。 (cplusplus.com/reference/cstdio/printf)
  • @nishant 或 %hhd%hhi%hho%hhx
  • 确实如此。但是,我不建议在此处使用 char 说明符,因为它还会将 ENTER 解析为字符。
  • 感谢您的回答。我明白了
【解决方案2】:

Never use scanfNever use scanf. 说真的,never use scanf

使用fgets(或getline,如果有的话)从用户那里读取整行输入,然后使用strtol 或其亲属strtodstrtoul 将字符串转换为数字。 strsep 也可能有用。

【讨论】:

  • @paulakis,如果使用正确,scanf 没有任何问题。人们遇到麻烦是因为他们不阅读它的文档。如果您的学校作业说使用 scanf,那么请学习使用 scanf,这是阅读文档的一个很好的练习。
  • @JackCColeman “输入溢出触发未定义的行为”最肯定是 scanf (规范)而不是程序员的错误,并且即使是模糊地正确使用它的绝对困难也是规范 IMNSHO。不要责怪受害者。
  • @Zack 这是在哪里说的?无处可去。
  • @JackCColeman C99 7.19.6.2p10:“如果[接收扫描结果的对象]没有合适的类型,或者如果转换的结果不能在对象,行为未定义。”阅读,哭泣。
  • @zack,即与输入溢出相同。
【解决方案3】:

通过读取其返回值检查scanf() 是否正常工作。如需快速入门,请在this link 阅读有关scanf() 的详细信息。

您正在做的是使用"%d" 将整数输入到unsigned char 变量中,因此scanf() 可能无法正常工作。

【讨论】:

    【解决方案4】:

    改变

    unsigned char one=0; unsigned char two=0;
    

    unsigned int one=0; unsigned int two=0;
    

    并且还使用%u 而不是%d 然后它将打印scanf() 之后的值。

    【讨论】:

      【解决方案5】:

      您将变量one 声明为字符:

      unsigned char one=0;
      

      但后来你告诉scanf 阅读int

      scanf("%d",&one);  /* %d means int */
      

      Int 大于 char(通常 4 字节与 1 字节),导致您描述的问题。

      将您的 scanf 更改为:

      scanf("%c",&one);  /* %c means char */
      

      那么当你打印出值的时候,也打印一个char:

      printf("The value is %c",one); /* %c means char */
      

      【讨论】:

      • 我不能说它是否与@paulakis 相关,因为他是 C 新手,但 scanf() 是使用 %c 阅读 char 的好功能吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-16
      • 2019-05-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多