tags:

views:

205

answers:

6
+9  Q: 

String arrays in C

I have an array of strings which when I iterate through and print its elements gives me unexpected results.

char currencies[][3] = {"EUR", "GBP", "USD", "JPY", "CNY"};

void show_currencies()
{
    int i;
    for(i=0; i<5; i++)
    {
        printf("%s - ", currencies[i]);
    }
}

when I call show_currencies() I get this on output.

EURGBPUSDJPYCNY - GBPUSDJPYCNY - USDJPYCNY - JPYCNY - CNY -

Can anyone explain this behaviour.

Thank you

+15  A: 

You are missing the nul terminators the strings are actually 4 characters long. Each string is then over writing the previous string's null terminator*. Try instead:

char currencies[][4] = {"EUR", "GBP", "USD", "JPY", "CNY"}; 

*As pointed out by caf it is not "over writing the previous string's null terminator" as the null terminator is never copied into the array. It is a fluke that the string is does not have garbled output after the final '-'.

Charles Beattie
Yep - that'll be it... You have to allow space in your array for the null terminator as well as the actual content...
Martin Milan
damn, took me so long to find how to declare string arrays, then I missed the length of each string :Dthanx for the help
martani_net
ephemient, that doesn't work (it's a compile-time error). You must declare the size of all but the left-most dimension (the compiler has to know how long a row is to handle indexing).
Matthew Flaschen
This is right, except that each string isn't "overwriting the previous string's null terminator" - the nul terminators are never written at all, because the arrays being initialised only have 3 chars each. (It was a complete fluke that the last array happened to be followed by a terminator at all).
caf
Thanks caf corrected above.
Charles Beattie
+2  A: 

Change

char currencies[][3]

to

char currencies[][4]

strings in C are NULL terminated, to make their handling (in printing, copying etc) easier. example: char str[] = "ABC"; will declare a string of 4 char with \0 as the last char (index 3).

As a tip whenever on printing a char array you get unexpected results you might wanna check to see if the char array is NULL terminated or not.

codaddict
+6  A: 

You're declaring it wrong. This will work. It just lets the compiler set up an array of pointers-to-const-chars:

const char *currencies[] = {"EUR", "GBP", "USD", "JPY", "CNY"};

EDIT: Making it a two-dimension array, like Charles Beattie's answer, works too, provided you allocate space for the null. Also, specify that chars are const, per Christoph.

Matthew Flaschen
actually, both work (if you leave space for the terminating zero in the original code), but your version might be better as compilers will have an easier time to optimize this; in both cases, you should add `const` qualifiers, though
Christoph
both the declarations are different. In OP's case, he is declaring a double char array, where as your declaration is a array of const char pointers. So, in your case he cannot modify the contents of the array, i mean he cannot do things like currencies[0][1] = 'x';
chappar
That's right, chappar. It does not look like he's intending to modify it.
Matthew Flaschen
A: 

Sure. "EUR" is four characters long - three for the letters, one for the terminating null character. Since you're explicitly specifying three-character arrays, the compiler is truncating, and so your data is strung together. You're lucky there is apparently a zero character at the end of the array, or you could get all sorts of garbage. Change your declaration to char currencies[][4].

David Thornley
A: 

My C is quite rusty, but try:

char currencies[][3] = {"EUR\0", "GBP\0", "USD\0", "JPY\0", "CNY\0"};

I'm just curious to know what happens

OscarRyz
The compiler should issue a warning.
ezpz
The same will hapen as your strings are 5 characters long. `"EUR\0" is equiv {'E','U','R','\0','\0'}`
Charles Beattie
+2  A: 

You don't have an array of strings but an array of array-of-char. You could use:

char* currencies[] = {"EUR", "GBP", "USD", "JPY", "CNY"};  // untested

to allow for strings of different lengths.

Henk Holterman
+1 from me for a way of avoiding counting..
Charles Beattie