scanf通过传递char

时间:2013-08-08 10:05:05

标签: c scanf

例如,我有以下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'变量接受用户输入会导致这样的结果吗?

2 个答案:

答案 0 :(得分:2)

将指针传递到与char对应的位置中的单个scanf%s始终是未定义的行为,因为%s为字符串写入至少两个字符(字符串主体至少有一个字符,空终止符。)

此外,将指针传递到与char对应的位置中的单个printf%s是未定义的行为,除非该char设置为'\0'(其中在您的计划中并非如此)。

因此,无论打印输出是什么,都依赖于编译器。同一程序可能会在另一台计算机上崩溃,或产生完全不同的输出。

如果您的特定编译器显示ognsubs之后的一个字符中位于内存中,那么它将以第二个字符开头打印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”

这就是为什么你得到你正在做的结果,但在不同的编译器上你可能会得到不同的结果。

不要在任何真实程序中做任何类似的事情。