It's almost certainly because your character arrays are not big enough to hold all the data you're reading. Specifically the string "zero"
(with it's \0
terminator) requires five bytes, not four. Writing beyond the end of an array is undefined behaviour and, once you do that, all behavioural guarantees are gone.
For example, when you declare:
char rd[4];
char rs[4];
char rt[4];
you may be laying out memory like this:
rt: [1] [2] [3] rs: [1] [2] [3] rd: [1] [2] [3]
+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
and executing the command:
sscanf ("or $a0, $t4, $zero", "or $%[^,], $%[^,], $%s", rd, rs, rt);
may cause the chunks of memory to be filled in the order shown, resulting in the following memory writes, where .
represents \0
:
rt: [1] [2] [3] rd: [1] [2] [3] rs: [1] [2] [3]
+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | a | 0 | . | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | | | | | t | 4 | . | |
+---+---+---+---+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+---+---+---+---+
| z | e | r | o | . | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
resulting in the final situation of:
rt: [1] [2] [3] rd: [1] [2] [3] rs: [1] [2] [3]
+---+---+---+---+---+---+---+---+---+---+---+---+
| z | e | r | o | . | 0 | . | | t | 4 | . | |
+---+---+---+---+---+---+---+---+---+---+---+---+
You can see there that the overwrite of rd
by rt
is what makes it look like nothing has been read into rd
.
Now note the use of the word may
above, there are no guarantees that memory will be laid out this way, it's just one possible explanation of why your results are happening.
The bottom line is that you shouldn't read more data into an array than you've allowed for.
As to how to solve this, there are numerous robust ways of getting input in C, such as this one.