initialising 2-dim character array

J

Jeremy Targett

Hello, I'm trying to initialise a two-dimensional array of characters, 12 by
60, with each entry maximum 6 characters wide. (It's a fix I'm making to an
old program which I learned just enough C for at the time, and since then
I've become rusty, and can't seem to figure this out.)

this (as you know) won't work:

char lily_pitch[12][60][7];

lily_pitch[0]={"c,", "des,", "d,", "ees,", "fes,", "f,", "ges,", "g,",
"aes,", "beses,", "bes,", "ces", "c", "des", "d", "ees", "fes", "f", "ges",
"g", "aes", "beses", "bes", "ces'", "c'", "des'", "d'", "ees'", "fes'", "f'",
"ges'", "g'", "aes'", "beses'", "bes'", "ces''", "c''", "des''", "d''",
"ees''", "fes''", "f''", "ges''", "g''", "aes''", "beses''", "bes''",
"ces'''", "c'''", "des'''", "d'''", "ees'''", "fes'''", "f'''", "ges'''",
"g'''", "aes'''", "beses'''", "bes'''", "ces''''"};

(then similar initialisations for lily_pitch[1] through [11])

What's the proper syntax, please? Should I be initialising the whole 12 by 60
array at once, in the declaration?

Also, will I have to pad out each entry so it's 6 characters?

Or maybe there's a completely different, better way - I just need to be able
to do something equivalent to

printf("%s",lily_pitch[j]);

during the program. If there's a better way than using arrays like this, I'd
appreciate any tips.

Many thanks,

JT

p.s. those entries in the array look funny don't they - if you're curious,
they're musical pitches formatted to be read by lilypond, a music typesetter.
 
J

Jeremy Targett

Jeremy Targett said:
Hello, I'm trying to initialise a two-dimensional array of characters, 12 by
60, with each entry maximum 6 characters wide. [snip]
this (as you know) won't work:
char lily_pitch[12][60][7];
lily_pitch[0]={"c,", "des,", "d,", "ees,", "fes,", "f,", "ges,", "g,",
"aes,", "beses,", "bes,", "ces", "c", "des", "d", "ees", "fes", "f", "ges",
"g", "aes", "beses", "bes", "ces'", "c'", "des'", "d'", "ees'", "fes'", "f'",
"ges'", "g'", "aes'", "beses'", "bes'", "ces''", "c''", "des''", "d''",
"ees''", "fes''", "f''", "ges''", "g''", "aes''", "beses''", "bes''",
"ces'''", "c'''", "des'''", "d'''", "ees'''", "fes'''", "f'''", "ges'''",
"g'''", "aes'''", "beses'''", "bes'''", "ces''''"};

I hate when this happens, but I just realized I can nest the arrays in a
declaration, using braces, so that's simple enough and solves the syntax
problem... except now I get the error "initializer-string for array of chars
is too long" when I compile. How do you deal with this? I imagine there is a
way to read in the data to the array somehow. Again, help greatly
appreciated.

And since it hasn't worked yet, I still don't know the answer to this other
question:
Also, will I have to pad out each entry so it's 6 characters?

Thanks -JT
 
K

Keith Thompson

Jeremy Targett said:
Hello, I'm trying to initialise a two-dimensional array of characters, 12 by
60, with each entry maximum 6 characters wide. (It's a fix I'm making to an
old program which I learned just enough C for at the time, and since then
I've become rusty, and can't seem to figure this out.)

this (as you know) won't work:

char lily_pitch[12][60][7];

lily_pitch[0]={"c,", "des,", "d,", "ees,", "fes,", "f,", "ges,", "g,",
"aes,", "beses,", "bes,", "ces", "c", "des", "d", "ees", "fes", "f", "ges",
"g", "aes", "beses", "bes", "ces'", "c'", "des'", "d'", "ees'", "fes'", "f'",
"ges'", "g'", "aes'", "beses'", "bes'", "ces''", "c''", "des''", "d''",
"ees''", "fes''", "f''", "ges''", "g''", "aes''", "beses''", "bes''",
"ces'''", "c'''", "des'''", "d'''", "ees'''", "fes'''", "f'''", "ges'''",
"g'''", "aes'''", "beses'''", "bes'''", "ces''''"};

(then similar initialisations for lily_pitch[1] through [11])

These are assignments, not initializers. The { expr, expr, expr }
syntax can only be used in an initializer. (C99's compound literals
are similar, but you probably don't want to use them if you want your
code to be portable.)
What's the proper syntax, please? Should I be initialising the whole
12 by 60 array at once, in the declaration?

Yes, that's probably the best approach.
Also, will I have to pad out each entry so it's 6 characters?

No, it will be padded with '\0' characters automatically.

Something like this should work:

char lily_pitch[12][60][7] =
{ { "c,", "des,", "d,", "ees,", ... },
{ "foo", "bar", ... },
...
{ "this", "is", "the", "last", "row" } };

If you're not going to be changing these values, you should probably
declare the array as "const".
 
J

Jeremy Targett

Dik T. Winter said:
char lily_pitch[12][60][7]; ...
"beses'''"

except now I get the error "initializer-string for array of chars
is too long" when I compile.
I think that is the culprit.

D'oh! After I found the maximum length of a string I added "double flats"
to this array... thank you for noticing! I thought it was my whole
initialisation string in the declaration that gcc was compaining was too
long.

Regards - JT
 
D

Dik T. Winter

> Dik T. Winter said:
> > In article said:
> > > > char lily_pitch[12][60][7]; > > ...
> > > > "beses'''"
> > >
> > > except now I get the error "initializer-string for array of chars
> > > is too long" when I compile.
>
> > I think that is the culprit.
>
> D'oh! After I found the maximum length of a string I added "double flats"
> to this array... thank you for noticing! I thought it was my whole
> initialisation string in the declaration that gcc was compaining was too
> long.

I do not think that a compiler would the complete initialser an
"initializer-string". However, rather than extending it to [9] (so to allow
for the zero byte terminator), I think you might make it a bit larger (that
will not waste much space). In that case you can add other octaves without
bothering about the exact size of the intialisation strings.
 
K

Keith Thompson

Dik T. Winter said:
D'oh! After I found the maximum length of a string I added "double flats"
to this array... thank you for noticing! I thought it was my whole
initialisation string in the declaration that gcc was compaining was too
long.

I do not think that a compiler would the complete initialser an
"initializer-string". However, rather than extending it to [9] (so to allow
for the zero byte terminator), I think you might make it a bit larger (that
will not waste much space). In that case you can add other octaves without
bothering about the exact size of the intialisation strings.

Also, consider this:

#include <stdio.h>
int main(void)
{
#ifdef USE_POINTERS
const char *s[][3]
#else
const char s[][3][3]
#endif
= { { "ab", "cd", "ef" },
{ "gh", "ij", "kl" },
{ "mn", "op", "qr" } };
int i, j;

for (i = 0; i < 3; i ++) {
for (j = 0; j < 3; j ++) {
printf("s[%d][%d] = \"%s\"\n", i, j, s[j]);
}
}
return 0;
}

This compiles, and produces the same output, whether USE_POINTERS is
defined or not. With USE_POINTERS defined, you have a two-dimensional
array of char*, each element of which points to a string. Without it,
you have a two-dimensional array of char[3], each element of which
*contains* a string (in a fixed-size array).

Of course it will behave differently in some cases involving sizeof
and unary "&" (pointers are not arrays, arrays are not pointers), but
either should be suitable if you're not planning to change anything in
the data structure after it's initialized.

Using pointers costs an extra sizeof(char*) bytes for each string, but
lets each string occupy only as much space as it actually needs; this
could be an advantage if a few of your strings are much longer than
average. For the size of problem the OP is dealing with, it probably
doesn't make a significant difference.

Note also that in both cases you don't need to specify the size of the
highest dimension; it's derived from the initializer.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top