Pages: [1]   Go Down
Author Topic: Reference variable with string  (Read 1652 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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
Logged

0
Offline Offline
God Member
*****
Karma: 2
Posts: 596
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So you'd like to write things like:

Code:
songNameNotes[songName]
songNameBeats[songName]

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:
#define SONG_HAPPYBIRTHDAY 0
#define SONG_ILOVEROCKNROLL 1
#define SONG_YOURSONG 2

and so on.

Then you can write things like:

Code:
songNameNotes[SONG_HAPPYBIRTHDAY]
songNameBeats[SONG_HAPPYBIRTHDAY]

(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:
int songIndex;

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

HTH
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 170
Posts: 12480
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You need a 2 dimensional array, and all three arrays use the same index.
Code:
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:
typedef struct {
  char name[20];
  int notes[100];
  int beat[100];
} Music ;

Music M[10] =
{
  {
    "hello",
    {1,2,3},
    {4,5,6},
  },
  {
    "goodbye",
    {12,23,34},
    {99,88,77}
  },
 ... // 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.

Succes!
Logged

Rob Tillaart

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

0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks both for your replies. smiley

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

Andy
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Thanks
Logged

0
Offline Offline
God Member
*****
Karma: 2
Posts: 596
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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.

HTH
Logged

Melbourne, Australia
Offline Offline
Full Member
***
Karma: 0
Posts: 219
Have you tried turning it off and on again?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

0
Offline Offline
God Member
*****
Karma: 2
Posts: 596
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pages: [1]   Go Up
Jump to: