我首先声明的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,$零”

有人可以解释吗?

最佳答案

几乎可以肯定,因为您的字符数组不够大,无法容纳您正在读取的所有数据。具体来说,字符串"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

关于c - C声明顺序错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16246116/

10-11 18:00