0

最初に宣言した 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 を入れましたが、読み込まれません。

これは私が読んでいる文字列です: "or $a0, $t4, $zero"

誰でもこれを説明できますか?

4

1 に答える 1

0

文字配列が、読み取っているすべてのデータを保持するのに十分な大きさではないため、ほぼ確実です。具体的には、文字列"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 | . |   |
+---+---+---+---+---+---+---+---+---+---+---+---+

rdbyの上書きにより、rt何も読み込まれていないように見えることがわかりますrd

上記の単語の使用に注意してください。mayメモリがこのようにレイアウトされるという保証はありません。これは、結果が発生する理由の 1 つの考えられる説明にすぎません。

肝心なのは、許可されているよりも多くのデータを配列に読み込むべきではないということです。

これを解決する方法については、このような C で入力を取得する堅牢な方法が多数あります

于 2015-10-15T08:21:32.337 に答える