11

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

2
  • any decent compiler should give error or at least warning for this Commented Mar 2, 2010 at 17:44
  • 1
    @chapper, @martani: I don't have a copy of the c standard near to hand, but I think that silently dropping the NUL byte in this case is explicitly allowed by the standard. At least at one time, there would have been a reasonable amount of code that used this technique to initialize fix-size char arrays, because it's much more concise than simply listing the char values one by one. Commented Mar 3, 2010 at 9:41

6 Answers 6

14

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 '-'.

Sign up to request clarification or add additional context in comments.

3 Comments

Yep - that'll be it... You have to allow space in your array for the null terminator as well as the actual content...
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).
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).
8

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.

3 Comments

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
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';
That's right, chappar. It does not look like he's intending to modify it.
2

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.

Comments

2

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.

Comments

0

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].

Comments

0

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

2 Comments

The compiler should issue a warning.
The same will hapen as your strings are 5 characters long. "EUR\0" is equiv {'E','U','R','\0','\0'}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.