【问题标题】:Scanning an integer using %c and a character using %d: unexpected results使用 %c 扫描整数和使用 %d 扫描字符:意外结果
【发布时间】:2013-07-25 15:40:39
【问题描述】:

我无法为以下代码的输出给出适当的理由。谁能帮帮我。

int main()
{
  int i;
  char ch;
  scanf("%c",&i);
  scanf("%d",&ch);
  printf("%d\n%c",i,ch);
  return 0;
}

输入输出:

input: 
a
45
output:
0
-

【问题讨论】:

  • 你期望输出是什么?
  • 一个很好的例子说明为什么你应该使用scanf。你告诉函数写一个char,然后你传递一个int的地址。你告诉函数写一个int,然后你传递一个char的地址。两者都是未定义的行为,所以你可以得到任何东西(包括程序崩溃)。
  • “我知道这是错误的代码 - 为什么它会出错?”
  • @LuchianGrigore 但是你知道它应该可以正常工作,它真的应该!!!!one11
  • 当我运行 gdb 时,在第一次 scanf() 后 i 的值为 97,但在第二次 scanf 后将值更改为 0。我想知道进行这些更改的原因是什么跨度>

标签: c++ c printf output scanf


【解决方案1】:

您正在将int 读入char。假设sizeof(int) != sizeof(char),这将导致scanf 写入超出ch 的末尾,导致未定义的后果。

您应该对int 参数使用%i 格式说明符,对char 参数使用%c

int main()
{
  int i;
  char ch;
  scanf("%c",&ch);
  scanf("%d",&i);
  printf("%d\n%c",i,ch);
  return 0;
}

【讨论】:

  • 我明白你在说什么,但是当我运行 gdb 时,在第一次 scanf() 之后 i 的值是 97,但在第二次 scanf 之后它将值更改为 0。我想知道什么是正在做出这些改变
  • @abhishekiiit 第二次调用scanf 导致sizeof(int)(可能>=4)字节被写入一个字节ch。这会导致未定义的行为。大概在您的情况下,它正在写入超出为ch 分配的内存并写入i 的内存,覆盖先前存储的字节 97。
【解决方案2】:

不要对scanfprintf 撒谎。没有什么好的结果。

在这种情况下,您尝试将 4 个字节填充到 1 的空间中 - 这显然不起作用,无论您挤压多少。您的程序没有崩溃的事实纯粹是运气。

【讨论】:

  • 我只是在试验:P 我想知道出了什么问题。我知道这是错误的,但我想知道值是如何变为 0 而不是别的。以及为什么 GDB 在第一次 scanf 后显示正确的值并在第二次 scanf 后将值更改为 0。
  • 因为你写的变量超出了你给scanf的变量大小。它获取变量的地址,而不是大小 - 大小来自“%d”或“%c”。
【解决方案3】:

这是Undefined behavior。您正试图通过告诉它在printfscanf 语句中分别弹出和推送不同的东西来混淆编译器。

【讨论】:

  • 当我运行 gdb 时,在第一次 scanf() 后 i 的值为 97,但在第二次 scanf 后将值更改为 0。我想知道进行这些更改的原因是什么跨度>
  • 正如我所说的它是未定义的,没有人能准确地说出那里发生了什么。请通过我提供的关于未定义的链接。
  • 请考虑一下我在回答中使用的 push 和 pop 这个词。它肯定会对您的问题有所启发。
猜你喜欢
  • 2017-11-23
  • 1970-01-01
  • 2016-03-12
  • 2011-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-27
相关资源
最近更新 更多