Go Down

Topic: Reference variable with string (Read 5647 times) previous topic - next topic

Andy M

Hi all,

I have a program that contains many variables with a standard format:
int songNameNotes[]
int songNameBeats[]

eg: happyBirthdayNotes & happyBirthdayBeats

I would like to be able to define which variable to used based on a string which contains just the song name.

So for example, i have:
Code: [Select]
char songName[] = "happyBirthday"

and I would like to be able to address the correct song's note and beat variables

What is the simplest way of doing this?

Many thanks


So you'd like to write things like:

Code: [Select]


This is not supported by C. Arrays can only be addressed by integer indexes, not string indexes.

You could for example use #define to associate song names with "song indexes":

Code: [Select]


and so on.

Then you can write things like:

Code: [Select]


(you must be careful when assigning values to the arrays, of course).

If the song name is entered by the user, e.g. via serial port, then you have to find a way to convert from string to integer. A not quite elegant but conceptually simple solution could be:

Code: [Select]

int songIndex;

if (strcmp(songName, "HAPPY BIRTHDAY") == 0) {
else if (strcmp(songName, "YOUR SONG") == 0) {
   songIndex = SONG_YOURSONG;
// etc.



You need a 2 dimensional array, and all three arrays use the same index.
Code: [Select]
char songName[][20] = {"happyBirthday", "little lamb", ... };
Note: you must declare the second index (max stringlen +1)  to a fixed number, and use the first to "search".

Better solution might be to use an array of structs. In every struct there is all info about one piece of music. Then you only need one index.

Code: [Select]
typedef struct {
 char name[20];
 int notes[100];
 int beat[100];
} Music ;

Music M[10] =
... // etc

Note that in the example above the sizes of the fields of the struct are fixed. This causes quite some overhead. A more elaborated version uses pointers for the fields, then the sizes of the fields can be allocated as needed.

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Andy M

Thanks both for your replies. :)

i got it working with the struct method as it is easier  when it comes to user input


Andy M

How would I adapt that struct so I didn't have to define the size at the beginning?



Each struct member would not be an array but a pointer to the appropriate data type. For example:

Code: [Select]

typedef struct {
 char* name;
 int* notes;
 int num_notes;
 int* beat;
 int num_beats;
} Music ;

Then you have to dynamically allocate memory for the arrays via malloc(), and remember to free() every pointer when you don't use it anymore. I haven't used malloc()/free() on the Arduino so far, so I can't tell how well it works.

The num_beats and num_notes could be avoided by taking an int number which is not a valid note nor a valid beat value and giving it the role of "array terminator", like 0x00 is used as "string terminator".

Just my 2 cents.



If you use malloc, you run the risk of loosing info from your stack.

You can use it, but you should never use it.


My feeling is that malloc() and friends are a "rich boy" thing (as a friend of mine would say). You seem to confirm this. I'll have to do some research sooner or later on this subject...

Go Up