2013-04-26 99 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