0

I want to print out a 2d array of char that contains mips registers. I want to print each register separately. But my current code prints out all the registers together. Is there a better way to do this problem, such as using a double pointer array of chars?

My code so far:
char reg[][3] = {
   {'$', 's', '0'},
   {'$', 's', '1'},
   {'$', 's', '2'},
   {'$', 's', '3'},
   {'$', 's', '4'},
   {'$', 's', '5'},
   {'$', 's', '6'},
};

int main(void){

   for(int i = 0; i < sizeof(reg); i++)
   {
      printf("%s\n", reg[i]);
   }
   return 0;
}
My output:
$s0$s1$s2$s3$s4$s5$s6
$s1$s2$s3$s4$s5$s6
$s2$s3$s4$s5$s6
$s3$s4$s5$s6
$s4$s5$s6
$s5$s6
$s6
But I want my output to be like this:
$s0
$s1
$s2
$s3
$s4
$s5
$s6
nonkooshy
  • 1
  • 1
  • 2
    `%s` requires a NUL terminate string. Your array is a sequence of characters and not a string. Increase the array second dimension size by 1 to ensure each entry is 0 terminated. Also, note that you can do `char reg[][4] = { "$s0", "$s1", ...}` – kaylum Nov 12 '21 at 03:32

2 Answers2

1

This is happening because in C, strings are null-terminated by convention. This means that printf called with the %s specifier will not stop until it reaches a null character.

To get your desired output without changing much of your code, you could add a null character at the end of each register like this

char reg[][4] = {
   {'$', 's', '0', 0},
   {'$', 's', '1', 0},
   {'$', 's', '2', 0},
   {'$', 's', '3', 0},
   {'$', 's', '4', 0},
   {'$', 's', '5', 0},
   {'$', 's', '6', 0}
};

but that's not very pretty. You can write it like this:

char reg[][4] = {"$s0", "$s1", "$s2", "$s3", "$s4", "$s5", "$s6"};

These strings will be null terminated by default.

Another way to do this without changing your array will be to specify how many characters to print for each print call, something like this:

printf("%.3s\n", reg[i]);

Edit: As pointed out by ice05's answer, your loop condition is also false. This code might generate a segmentation fault. A common way to handle this case in C is to use a preprocessor macro, for example:

#define REGISTER_STRING_SIZE 3

char reg[][REGISTER_STRING_SIZE] = {
   {'$', 's', '0'},
   {'$', 's', '1'},
   {'$', 's', '2'},
   {'$', 's', '3'},
   {'$', 's', '4'},
   {'$', 's', '5'},
   {'$', 's', '6'},
};

And then in your loop,

    for(int i = 0; i < sizeof(reg)/REGISTER_STRING_SIZE; i++)
    {
        printf("%.3s\n", reg[i]);
    }

This is not very elegant and I would recommend treating the registers as strings (adding the null terminator).

jacky la mouette
  • 523
  • 4
  • 17
1

First of all, it may be easier to treat the register names as strings, (i.e., char arrays terminated by a \0), especially since you are using %s to print out the string (the %s specifier expects a NUL terminated array of chars). So, you want the second dimension of the 2D reg array to be 4, in order to hold the \0:

char reg[][4] = {
   {'$', 's', '0', '\0'},
   {'$', 's', '1', '\0'},
   {'$', 's', '2', '\0'},
   {'$', 's', '3', '\0'},
   {'$', 's', '4', '\0'},
   {'$', 's', '5', '\0'},
   {'$', 's', '6', '\0'}
};

Alternatively, you could write these out as strings directly:

char reg[][4] = {
   "$s0",
   "$s1",
   "$s2",
   "$s3",
   "$s4",
   "$s5",
   "$s6"
};

Now onto the loop. The sizeof(reg) in the loop condition gives you the size (in bytes) of the 2D array reg which is 7*4 = 28.

What you really want to loop over is the number of rows in the 2D array. In your case, since the size of each register name is 4 (remember to include the NUL terminator!), you could do the following:

for(int i = 0; i < sizeof(reg)/4; i++)
{
    printf("%s\n", reg[i]);
}
ice05
  • 499
  • 2
  • 8