例如,我有以下c代码:
printf("please input : \r\n" ) ;
char ogn, subs;
scanf("%s %s", &ogn, &subs);
printf("the two values are: %s %s", &ogn, &subs);
运行代码时,例如我输入" abc def"和考试ogn,subs,
我只是得到ogn =" ef"和subs =" def&#34 ;;
有人可以帮我解释一下吗?我知道一个'字符串' case a' char array'应该提供,但在这里我只是想知道为什么' char'变量接受用户输入会导致这样的结果吗?
答案 0 :(得分:2)
将指针传递到与char
对应的位置中的单个scanf
到%s
始终是未定义的行为,因为%s
为字符串写入至少两个字符(字符串主体至少有一个字符,空终止符。)
此外,将指针传递到与char
对应的位置中的单个printf
到%s
是未定义的行为,除非该char设置为'\0'
(其中在您的计划中并非如此)。
因此,无论打印输出是什么,都依赖于编译器。同一程序可能会在另一台计算机上崩溃,或产生完全不同的输出。
如果您的特定编译器显示ogn
在subs
之后的一个字符中位于内存中,那么它将以第二个字符开头打印subs
的内容。
要解决此问题,请将至少四个字符的数组分配给字符串变量(足以容纳三个字符的变量),并使用size说明符来限制输入:
char ogn[4], subs[4]; // enough for abs def; expand if you need more chars
scanf("%3s %3s", ogn, subs);
答案 1 :(得分:1)
结果实际上是未定义的行为。
你的程序包含你的记忆:
潜艇| ogn | m | m | m | ...
其中m只是你的程序分配的随机内存(不要问我为什么它在那里,如果它不存在它会被分割出来。)
现在scanf将“abc”加载到ogn中,所以内存看起来像这样
潜艇| 'a'| 'b'| 'c'| '\ 0'| ...
现在scanf将“def”加载到subs:
'd'| 'e'| 'f'| '\ 0'| '\ 0'| ..
现在你告诉它从ogn打印一个字符串。直到第一次终止'\ 0':
“DEF”
现在你告诉它从sub到'0'打印一个字符串:
“EF”
这就是为什么你得到你正在做的结果,但在不同的编译器上你可能会得到不同的结果。
不要在任何真实程序中做任何类似的事情。