文字配列が、読み取っているすべてのデータを保持するのに十分な大きさではないため、ほぼ確実です。具体的には、文字列"zero"
(\0
ターミネータを含む) には 4 バイトではなく 5 バイトが必要です。配列の末尾を超えて書き込むことは未定義の動作であり、それを行うと、すべての動作保証が失われます。
たとえば、次のように宣言する場合:
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
byの上書きにより、rt
何も読み込まれていないように見えることがわかりますrd
。
上記の単語の使用に注意してください。may
メモリがこのようにレイアウトされるという保証はありません。これは、結果が発生する理由の 1 つの考えられる説明にすぎません。
肝心なのは、許可されているよりも多くのデータを配列に読み込むべきではないということです。
これを解決する方法については、このような C で入力を取得する堅牢な方法が多数あります。