0

Whichever char[] I declare first, does not get read into by the sscanf function.

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

For example, I put rd first, and rd is not read into. I put rs first and it is not read into.

This is the string I am reading: "or $a0, $t4, $zero"

can anyone explain this?

user1248171
  • 109
  • 1
  • 4
  • 2
    The string `"zero"` doesn't fit in a `char[4]`, you need a `char[5]` for that. The 0-terminator is apparently stored in the first byte of `rd` here. – Daniel Fischer Apr 26 '13 at 22:33
  • 1
    Just say no to `sscanf`; Numerous references, such as [this](http://stackoverflow.com/questions/2430303/disadvantages-of-scanf). – Tom Blodget Apr 26 '13 at 22:41

1 Answers1

0

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.

Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953