2013-04-26 101 views
0

无论我首先声明的char [],都不会被sscanf函数读取。C声明顺序错误

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没有读入。我先把它放进去,它不会被读入。

这是我读的字符串: “或$ A0,$ T4,$零”

谁能解释一下吗?

+2

字符串'“零”不适合'char [4]',因此您需要一个'char [5]'。 0结束符显然存储在'rd'的第一个字节中。 – 2013-04-26 22:33:56

+1

只对'sscanf'说不;许多参考资料,如[this](http://stackoverflow.com/questions/2430303/disadvantages-of-scanf)。 – 2013-04-26 22:41:27

回答

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); 

可以导致楚内存NKS中显示的顺序填写,导致下面的内存写入,其中.代表\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 | . | | 
+---+---+---+---+---+---+---+---+---+---+---+---+ 

你可以看到有该覆盖rdrt是什么使它看起来像什么都没有被读入rd

现在注意使用上面的单词may,但不能保证内存将以这种方式布置,这只是解释为什么会发生结果的一种可能的解释。

底线是你不应该读更多的数据到数组中,而不是你允许的。

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