首页 > 解决方案 > 为什么 scanf(%s) 中的 char 参数即使乱序也不能显示在 %c 中?

问题描述

char num1, num2;
scanf("%s %s", &num1, &num2);
printf("num1=%c, num2=%c", num1, num2);

我在 Mac 的 Visual Studio 上执行了上面的代码,情况如下:

Input: a b   => num1=, num2=b
Input: ab c  => num1=, num2=c
Input: a bc  => num1=c, num2=b
Input: ab cd => num1=d, num2=c

我绝对知道 %s 应该是 %c,但我想知道为什么第一个参数 char num1 不能在 %s 中正确显示。

此外,如果我们输入“a bc”或“ab cd”,则 num2 的值在 num1 之前。这看起来很混乱。

C 中导致这些奇怪输出的原因或机制是什么?你的电脑上的结果一样吗?我认为知道原因比约定更重要。

标签: cscanfundefined-behaviorc-stringsstdio

解决方案


该程序具有未定义的行为。

格式说明符%s将零字符附加到相应参数占用的内存中。

不过我可以解释程序输出。

似乎在堆栈中,变量num1跟随变量num2

所以当输入是

nput: a b

然后在变量的地址中num2写入两个字符'b''\0';字符'\0'占用变量的内存num1

所以输出是

num1=, num2=b

当输入为

Input: ab c

当再次将终止零写入变量占用的内存时num1

所以你得到与上面相同的输出

num1=, num2=c

当输入为

Input: a bc

然后在被寻址的内存&num2中写入三个字符'b''c''\0'。所以字符'b'被放置在变量num2中,字符'c'被放置在变量中num1并且终止的零覆盖了超出为变量分配的内存的内存。

所以输出是

num1=c, num2=b

在最后一种情况下,当输入是

nput: ab cd

那么输出将是

num1=d, num2=c

如上所述。


推荐阅读