我首先声明的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/