-1

例如,我有以下 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";

有人可以为我解释一下吗?我知道在“字符串”情况下应该提供“字符数组”,但在这里我只想知道为什么接受用户输入的“字符”变量会导致这样的结果?

4

2 回答 2

2

在对应的位置传递指向单个charto的指针始终是未定义的行为,因为为字符串写入至少两个字符(至少一个字符用于字符串的主体,以及一个空终止符)。scanf%s%s

此外,在对应的位置传递指向单个charto的指针是未定义的行为,除非该 char 设置为(在您的程序中不是这种情况)。printf%s'\0'

因此,您拥有的任何打印输出都严重依赖于编译器。同一个程序可能会在另一台计算机上崩溃,或者产生完全不同的输出。

对于您的特定编译器,它似乎ogn位于内存中的一个字符之后subs,因此它会打印subs从第二个字符开始的内容。

要解决此问题,请将至少四个字符的数组分配给您的字符串变量(足以容纳三个字符的变量)并使用大小说明符来限制输入:

char ogn[4], subs[4]; // enough for abs def; expand if you need more chars
scanf("%3s %3s", ogn, subs);
于 2013-08-08T10:10:39.393 回答
1

结果实际上是未定义的行为。

您的程序会像这样打包您的内存:

潜艇 | 奥恩 | 米 | 米 | 米 | ...

其中 m 只是您的程序分配的随机内存(不要问我为什么它在那里,如果它不在那里它会出现段错误。)

现在scanf将“abc”加载到ogn中,所以内存看起来像这样

潜艇 | '一个' | 'b' | 'c' | '\0' | ...

现在 scanf 将“def”加载到 subs 中:

'd' | 'e' | 'f' | '\0' | '\0' | ..

现在你告诉它从 ogn 打印一个字符串。因此直到第一个终止'\ 0':

“定义”

现在你告诉它从 sub 到 '\0' 打印一个字符串:

“ef”

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

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

于 2013-08-08T10:18:54.730 回答