Compare strings and find index of string array?

Hey all,

With my program, the user enters a musical note value and octave in one string, like A#4 or C8 etc

What i want to do is compare the first 1 or 2 letters of the note value (i can do the octave (last part of the string) later) to a predesignated string array (NOTE_LIST) and get the index of the array that matches.

I've tried the following code but as strcmp output is a 1 or 0 its obviously not going to work...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
string NOTE_LIST[12] = { "A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#" };
	int NOTE_ROW;
	string NOTEX;

	if (NOTE_VALUE.length == 3)
	{
		NOTEX = NOTE_VALUE[0] + NOTE_VALUE[1];
	}
	else if (NOTE_VALUE.length == 2)
	{
		NOTEX = NOTE_VALUE[0];
	}

	for (int i = 0; i > 12; i++)
	{
		NOTE_ROW = strcmp(NOTEX, NOTE_LIST[i]);
	}



How can i achieve what i want. Is Compare a better choice or is there some other way to do it?

Thanks,

Paul..
Last edited on
create an int variable and a bool variable that starts with false

Then two for loops, outer loop like yours [i] for the list of strings and inner loop that will check every character in both strings if they are equal (by accessing the indexes [0][1][2].. [j] etc).

within the inner loop put an if statement:
if (both strings differ on the current [j] character then bool is false)
else (true)

now, under the inner loop but within the outer loop, another if statement:
if (bool is true) then assign [i] to the temp and break, and here you go.
else just continue and iterate next of the outer loop to start all over again with the next string in the list.

Hope this helps
Last edited on
Instead of
1
2
3
4
	for (int i = 0; i > 12; i++)
	{
		NOTE_ROW = strcmp(NOTEX, NOTE_LIST[i]);
	}


Try
1
2
3
4
5
6
7
8
9
	for (int i = 0; i > 12; i++)
	{
		if (0 != strcmp(NOTEX, NOTE_LIST[i])) 
                {
                        NOTE_ROW =i;
                        break;
                }

	}


That's the idiom, however, since your'e already using strings, prefer the built-in comparison operator to strcmp:

if (NOTEX == NOTE_LIST[i]) NOTE_ROW = i;

*edit - got my strcmp return value twisted
Last edited on
didn't really look at the rest of the code before...

Your loop will never run, do you mean "i < 12" not "i > 12"?
Hey both of you, thanks for you replies...

So far I have:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// FUNCTION:
void GET_MIDI_NUMBER()
{
	string NOTE_LIST[12] = { "A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#" };
	int NOTE_ROW;
	int NOTE_COL;
	string NOTEX;

	//switch (NOTE_VALUE.length)

	if (NOTE_VALUE.length() == 3)
	{
		NOTEX = NOTE_VALUE[0] + NOTE_VALUE[1];
	}
	else if (NOTE_VALUE.length() == 2)
	{
		NOTEX = NOTE_VALUE[0];
	}

	

	for (int i = 0; i < 12; i++)
	{
		if (NOTEX == NOTE_LIST[i])
		{
			NOTE_ROW = i;
			break;
		}
	}

	NOTE_COL = NOTE_VALUE[NOTE_VALUE.length() - 1];

	cout << "THE NOTE CHOSEN = " << NOTE_VALUE << endl;
	cout << "NOTEX = " << NOTEX << endl;
	cout << "NOTE COLUMN (OCTAVE) = " << NOTE_COL << endl;
	cout << "THE INDEX OF NOTE_LIST THAT MATCHES IS: " << i;

}
// END FUNCTION.. 



Which runs fine but looking at what its outputting, its the ASCII equivilants.

For example, if I chose G#9 as the note, the cout(s) display the following:

THE NOTE CHOSEN = G#9 (this is correct)..
NOTEX = j (this is the added ASCII values of G and #, so 71 + 35 = 106 which is j
NOTE COLUMN (OCTAVE) = 57 (this the ASCII for 9 so technically correct)
THE INDEX OF NOTE_LIST THAT MATCHES IS: 0 (which is totally wrong - it should be 12)


Now apart from the index being always 0, the rest display the ASCII codes and i want the string for NOTEX to be displayed and the 9 instead of 57 for the octave.

I've tried using itos with them but itos is not recognised. What header do i need to include?

Paul..
Tipaye, i even tried:
 
for (int i = 0; i < 12; i++)


but the index is always 0..
but isn't the condition in the middle of the for loop?

so initialise variable; loop until condition is met; increment

so the condition to break the loop would be when i is more than 12?
TYPES! That's the problem.

What type is NOTE_VALUE? I'm assuming it is of type std::string.

in line 13 NOTEX = NOTE_VALUE[0] + NOTE_VALUE[1]; You are adding the numerical values of 2 chars and the result is an arithmetic expression.
Try adding 2 strings instead:
NOTEX = NOTE_VALUE.substr(0,2) ;
Or something similar...

Also be aware that you are assigning a char to a string in line 17. Instead do something similar to the above.
NOTEX = NOTE_VALUE.substr(0,1) ;

And in line 31 NOTE_COL = NOTE_VALUE.substr(NOTE_VALUE.length() - 1, 1);

In line 36, i is not in scope, so you can't use it. Try using NOTE_ROW instead. Also consider what to do if NOTEX is not found in NODE_LIST, NOTE_ROW remains uninitialised.

@hardwired:
for (int i = 0; i > 12; i++)
This means:

1. set the value in i to 0
2. if the value in i is greater than 12 execute the loop, otherwise jump to step 5
3. increment the value in i
4. go back and repeat from step 2
5. this is after the loop...

The condition is tested, and since i is definitely not greater than 12, the loop is never executed.

for (int i = 0; i < 12; i++)

This time the loop will be executed, and i incremented, the condition will be tested and since i is still less than 12, the loop will be executed again, i incremented again, and so on, until i equals 11, is incremented and is therefore no longer less than 12, at which point the loop will end.

The break in the middle is so you stop searching once you find what you're looking for.
Hey tipaye, thanks for that breakdown of it all. Learnt a lot and got it working now. Thanks so much :)
Topic archived. No new replies allowed.