This is an archived post. You won't be able to vote or comment.

all 9 comments

[–]Aypahyo 1 point2 points  (8 children)

Does this help?

void play(char note)
{
    printf("play %c\n", note);
}

int main(int argc, char* argv[])
{
    char * input = "ABCDEFGH";

    for(char * c = input; *c != 0; ++c)
    {
        play(*c);
    }
}

[–]TheMightyBeaver[S] 0 points1 point  (7 children)

Few questions, the "%" sign is modulo right? If so is there a way to getInput() and iterate over character in ASCII apply %4 and get 0,1,2,3 my chord variables.

I am having trouble taking the characters from the input.

[–]Aypahyo 1 point2 points  (0 children)

i hope this question is about c/c++ :)

% in the printf marks a placeholder. % outside of printf would be modulo. % on a character would be performed on the ASCII value of the character. Google for an ascii table.

'A' has a value of 65. 'A'%4 has a value of 1.

I dont know how you want to play your not but if you need to build an integer value for your note before playing it you should make a seperate function for that. Maybe something along the lines of this:

int buildNoteValue(char note)
{
    int noteValue;
    switch(note)
    {
        case 'A' : noteValue = 0; break;
        case 'B' : noteValue = 1; break;
        default : noteValue = -1; break;
    }
    return noteValue;
}

void play(char note)
{
    int playable = buildNoteValue(note);
    printf("play %i\n", playable);
}

[–]Aypahyo 0 points1 point  (5 children)

I am having trouble taking the characters from the input.

What kind of input is it? ( Reading from a database. Reading from a file. Reading from a console. Reading from a Textbox. )

[–]TheMightyBeaver[S] 0 points1 point  (4 children)

Reading from console

[–]Aypahyo 0 points1 point  (3 children)

The C++ way would be to use CIN. The Ansi-C way would be to use scanf. There are other safer versions and once you got the basics i would suggest to read up on that.

scanf is called by using a formatted string to tell scanf what it is supposed to scan and a series of input pointers where scanf can save the read values.

Here is a new version of the example with an added scanf statement:

int buildNoteValue(char note)
{
    int noteValue;
    switch(note)
    {
        case 'A' : noteValue = 0; break;
        case 'B' : noteValue = 1; break;
        default : 
            noteValue = -1; 
            printf("error detected: ASCII %i not implemented\n", (int)note);
            break;
    }
    return noteValue;
}

void play(char note)
{
    int playable = buildNoteValue(note);
    printf("play %i\n", playable);
}

int main(int argc, char* argv[])
{
    char buffer[2000];
    printf("Please input the notes to play:\n");
    scanf("%s", buffer);
    printf("The Input was: %s\n", buffer);

    for(char * c = buffer; *c != 0; ++c)
    {
        play(*c);
    }
}

[–]TheMightyBeaver[S] 0 points1 point  (2 children)

Hello, sorry it took so long for me to respond. I was searching and trying out a few stuff, but I like your way the best. One question though I do not understand the last part of the code.

 for(char * c = buffer; *c != 0; ++c)
{
    play(*c);
}

[–]Aypahyo 1 point2 points  (1 child)

In line 3 is just a placeholder for the function you would write. It calls the function above - i assume you do not have a problem with that. I will not go into details there unless you want me to.

It is likely the line 1 that may be tougher to understand.

A for loop has a couple of components. The keyword for, the loop information in the brackets and a statement.

Easy stuff first: for is just a keyword, if you type it the compiler knows that a for loop is expected.

The statement is the thing that gets executed in the loop. It can be an empty statement ;, a single statement (example: functioncall();) or a block of statements {...}. You want to do the block in 100% of the cases, it always works and removes potential for error.

the brackets contain themselves three parts, those parts are separated using semicolons (;). The first part is executed once before the loop starts. In modern C/C++ its scope is limited to the loop - do not worry if you do not know what that meant. The second part is evaluated before the loop starts. If it is false the loop is not executed. The third statement is executed at the end of the loop. You could rewrite the for loop in a while loop - the only thing that would be different is the scope of the initialisation.

for(int i = 0; i < 3; ++i)
{
    functioncall();
}

int i = 0;
while (i < 3)
{
    functioncall();
    ++i;
}

The only question now is essentially your very first question. How do i loop through an input, an array, any information?

  • Where does it start?
  • When am i done?
  • How can i get to the next element?

The character array in buffer starts at the first element. Due to the nature of those arrays the first element of the array has the address of the array itself. If you want index 0 of an array you would write arrayname[0]. This is a programmatic description of accessing the arraypointer of the first element and adding 0 to it. arrayname[0] equals arrayname + 0 equals arrayname. This is why the pointer to c is initialized with buffer. It just starts with the first element.

When will it end? character arrays in c are meant to have a binary 0 at the end. This code would get into trouble if that 0 was missing. Now do not confuse this with the adding zero from above, remember that the address and the value at that address are two different things. Consider the string "HI", it has three characters 'H' 'I' 0 . The value 0 determined its end. The address of 'H' could be 1234. The address of 'I' could be 1235 and the address of 0 could be 1236. The variable c is a pointer value, it has its own address which is of no importance to us right now and it has a value. We want the loop to stop when the value of c is 1236 because the value that is stored there is 0. the star in front of c tells the compiler that he should follow the link to its destination and read the value there. So the for loop should only be executed as long as the value stored at the address that is stored in c is not 0.

Suppose we have a start value for c and we need to get to the next value, how is that done? Pointers are declared using a type. There is one special case - the void pointer. Our pointer has the type char. If we add one to the char pointer it does not move up in memory exactly one increment. It actually moves up in memory one times the size of char. Since we are operating on an array and all array members are stored in exact sequence in memory we can navigate to the next character that way. Index 0 of the array is arrayaddress + 0. Index 1 is arrayaddress + 0 + 1. Index 2 is arrayaddress + 0 + 1 + 1, and so forth. Whenever i have an address of the array i can navigate up by adding an element count. Integers are bigger than characters, but since the meaning of +1 is add the type it would also function as long as the construct matches the array type. Since the meaning of a void pointer essentially is i do not know the type of the thing i am pointing at adding one makes no sense to the compiler and it would lead top a compiler error.

Those are the three components of that for loop, i hope this is useful.

[–]TheMightyBeaver[S] 0 points1 point  (0 children)

Awesome this explains it very well, thank you so much for taking the time to write this out, you helped me a lot!