C声明顺序错误

时间:2013-04-26 22:24:44

标签: c declaration

我首先声明的char []不会被sscanf函数读入。

char rd[4];
char rs[4];
char rt[4];
sscanf(line, "or $%[^,], $%[^,], $%s", rd, rs, rt);
printf("RD: %s, RS: %s, RT: %s\n", rd, rs, rt);

例如,我把rd放在第一位,而rd没有被读入。我把rs放在第一位,它没有被读入。

这是我正在阅读的字符串: “或$ a0,$ t4,$ 0”

任何人都可以解释这个吗?

1 个答案:

答案 0 :(得分:0)

几乎可以肯定,因为你的角色数组不够大,无法容纳你正在阅读的所有数据。具体来说,字符串"zero"(带有\0终结符)需要五个字节,而不是四个字节。超出数组末尾的写法是未定义的行为,一旦你这样做,所有的行为保证都会消失。

例如,当您声明:

char rd[4];
char rs[4];
char rt[4];

可能正在布局这样的记忆:

 rt: [1] [2] [3] rs: [1] [2] [3] rd: [1] [2] [3]
+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+

并执行命令:

sscanf ("or $a0, $t4, $zero", "or $%[^,], $%[^,], $%s", rd, rs, rt);

可能导致内存块按所示顺序填充,导致以下内存写入,其中.代表\0

 rt: [1] [2] [3] rd: [1] [2] [3] rs: [1] [2] [3]
+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   | a | 0 | . |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   | t | 4 | . |   |
+---+---+---+---+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+---+---+---+---+
| z | e | r | o | . |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+

导致最终情况:

 rt: [1] [2] [3] rd: [1] [2] [3] rs: [1] [2] [3]
+---+---+---+---+---+---+---+---+---+---+---+---+
| z | e | r | o | . | 0 | . |   | t | 4 | . |   |
+---+---+---+---+---+---+---+---+---+---+---+---+

您可以看到rd覆盖rt是因为它看起来没有被rd读入。

现在注意使用上面的单词may,无法保证记忆将以这种方式布局,这只是对结果发生原因的一种可能解释。

最重要的是,您不应该将更多数据读入数组而不是您允许的数据。

至于如何解决这个问题,有很多可靠的方法可以在C中获取输入,例如this one