Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Some help with C please.

Options
  • 23-09-2008 4:46pm
    #1
    Registered Users Posts: 3,502 ✭✭✭


    Hi everyone, I know this is a newbie question but could someone tell me what is wrong with my code? I want to input six and get an average. I can input grades, the average is working but I it skips every second scanf. So in effect i can only enter three values even though it repeats six times. Here is the full code.

    BTW: Sorry about this text being bolded out.



    #include <stdio.h>

    #include <stdlib.h>



    int main(int argc, char *argv[])

    {

    // declarations



    char grade;

    float sum;

    int count;



    count=1;



    // nested loop

    while(count>0&&count<7)

    {

    printf("Input your grade\n ");

    scanf("%c",&grade);



    if (grade=='a'||grade=='A')

    {

    sum=sum+4;

    }



    if(grade=='b'||grade=='B')

    {

    sum=sum+3;

    }



    if(grade=='c'||grade=='C')

    {

    sum=sum+2;

    }



    if (grade=='d'||grade=='D')

    {

    sum=sum+1.5;

    }



    if (grade=='f'||grade=='F')

    {

    sum=sum+0;

    }

    printf("\n");

    count=count+1;

    }



    // Getting the average

    sum=sum/6;



    // Printing out the average

    printf("\nThe average value of your scores in %f\n" ,sum);



    system("PAUSE");

    return 0;

    }

    Any help would be much appreciated :)


Comments

  • Registered Users Posts: 26,579 ✭✭✭✭Creamy Goodness


    guessing here but isn't a carraige return counted as a character. I'm on a bus atm so I can't test it but I think that might be what's happening

    To test what's happening write you if statements as an if-elseif-else block and print out the character that was inputted from the keyboard


  • Registered Users Posts: 1,996 ✭✭✭lynchie


    As Cremo said, you are in fact typing two characters 'A' and '<enter>' Enter or the carriage return is also considered a character so after the first scanf() reads 'A' off the input buffer, the carriage return is still there. When it executes the second scanf() the input buffer already contains a character so it reads it from there instead of asking you to type something. (More info http://www1.coe.neu.edu/~emelas/char.html)

    Anyway, either flush the buffer using fflush(stdin) or assign the extra character to a dummy variable.


  • Registered Users Posts: 3,502 ✭✭✭thefinalstage


    So when I press 'a' then the return key it reads two characters? Hmmmm
    Now to figure out how to prevent this....


  • Registered Users Posts: 9,579 ✭✭✭Webmonkey


    As said above you can use fflush(stdin) or read in another charactor to skip over.
    int main(int argc, char *argv[])
    
    {
    
        // declarations
        
        char grade;
        float sum;
        int count;
    
        for (count=0; count <6; count++)
        {
            printf("Enter Grade: ");
            grade = getchar();   
            fflush(stdin); 
            
            if (grade=='a'||grade=='A') 
                sum += 4;   
            else if(grade=='b'||grade=='B')
                 sum += 3;
            else if(grade=='c'||grade=='C')
                 sum += 2; 
            else if (grade=='d'||grade=='D')
                 sum += 1.5;
            else if (grade=='f'||grade=='F')
                 sum += 0;
        }
    
        // Getting the average  
        sum=sum/6;
        
        // Printing out the average
        printf("\nThe average value of your scores in &#37;f\n" ,sum);
    
        system("PAUSE");
        
        return 0;
    
    }
    

    Also bit cleaner code.

    Hints:
    - To read charactor use getchar().
    - If your if statements only have one statement, no need for braces (though lot people dislike this)
    - Use else if for the rest instead of if, this ensures that only one if gets executed - faster.
    - For loops in my opinion looks nicer.
    - sum = sum + 4 is same as sum += 4


  • Registered Users Posts: 3,502 ✭✭✭thefinalstage


    So thats how its done! Thanks a lot everyone :)


  • Advertisement
  • Registered Users Posts: 26,579 ✭✭✭✭Creamy Goodness


    no problems, good luck with the C, i'm looking forward to going back to it for the first time in 3 years this year. can't wait \o/


  • Registered Users Posts: 9,579 ✭✭✭Webmonkey


    Cremo wrote: »
    no problems, good luck with the C, i'm looking forward to going back to it for the first time in 3 years this year. can't wait \o/
    Likewise for Final Yr Project, so much more fun than the Higher level languages :)


  • Registered Users Posts: 21,257 ✭✭✭✭Eoin


    Would it be a little simpler to convert the character to upper or lower case rather than doing the OR statements each time?
    Webmonkey wrote: »
    - If your if statements only have one statement, no need for braces (though lot people dislike this)

    I personally find it that little bit harder to read someone else's code when braces aren't used. Also, if you need to add an extra line of debugging code, you end up having to add in the braces anyway.


  • Registered Users Posts: 9,579 ✭✭✭Webmonkey


    eoin_s wrote: »
    Would it be a little simpler to convert the character to upper or lower case rather than doing the OR statements each time?



    I personally find it that little bit harder to read someone else's code when braces aren't used. Also, if you need to add an extra line of debugging code, you end up having to add in the braces anyway.
    True, you can use tolower() on the character.

    Yeah, true when debugging but I don't know, I think it looks cleaner without braces just as long as you make sure you've indented it and put one or two new lines underneath so it stands out.

    End of day, its what ever you prefer yourself but if your code is going to be used or modified in the future by another developer it probably is best to have the braces as it seems most developers prefer it there. Just thought id let the OP know such thing exists anyways.

    Edit: you must include ctype.h to use tolower OP.


  • Registered Users Posts: 3,502 ✭✭✭thefinalstage


    I have a fresh one for you. The progra is suppose to print out "please enter an integer" in the second function and stop when I enter an integer. I have been trying to make this work but the the second scanf will inside the while loop will not work. Any idea why? I am also suppose to clear the buffer after the first integer number has been entered. Any idea how?
    This is just regular old c this time


    #include <stdio.h>
    #include <stdlib.h>

    int getInt(void);

    int main(int argc, char *argv[])
    {
    int x;
    x = getInt();
    printf("\nThe value entered was %d\n",x);
    system("Pause");
    return 0;
    }
    int getInt(void)

    {
    int z,scanResult;

    scanResult=scanf("%d",&z);

    while(scanResult==0)
    {
    printf("Please enter an integer\n");
    scanf("%d",&z);
    }

    return z;
    }


  • Advertisement
  • Registered Users Posts: 1,996 ✭✭✭lynchie


    I have a fresh one for you. The progra is suppose to print out "please enter an integer" in the second function and stop when I enter an integer. I have been trying to make this work but the the second scanf will inside the while loop will not work. Any idea why? I am also suppose to clear the buffer after the first integer number has been entered. Any idea how?
    This is just regular old c this time


    #include <stdio.h>
    #include <stdlib.h>

    int getInt(void);

    int main(int argc, char *argv[])
    {
    int x;
    x = getInt();
    printf("\nThe value entered was %d\n",x);
    system("Pause");
    return 0;
    }
    int getInt(void)

    {
    int z,scanResult;

    scanResult=scanf("%d",&z);

    while(scanResult==0)
    {
    printf("Please enter an integer\n");
    scanf("%d",&z);
    }

    return z;
    }

    for a start your while loop will loop forever as you are never assigning anything to scanResult on each iteration. For flushing buffers refer to my post above.


  • Registered Users Posts: 3,502 ✭✭✭thefinalstage


    lynchie wrote: »
    for a start your while loop will loop forever as you are never assigning anything to scanResult on each iteration. For flushing buffers refer to my post above.

    I was trying to assign it a vriable by using the scanf. But for some reason its not running that piece of code, I am at a loss.

    I tried scanResult is equal to the scanf in the code but it still wont let me input anything. Any ideas?


  • Registered Users Posts: 9,579 ✭✭✭Webmonkey


    scanf returns a integer (the number of characters entered) so that can't be used to test.

    Scanf expects a pointer (memory address of a variable), hense why you place an & before the variables name in the second argument. The read in data will then exist in this variable.

    I'm guessing by your code that you want to keep prompting user to enter value until they enter an integer. Is there a predefined range in this, if so you just have to check if the value is between these values and exit if so.
    The problem is, you are scanfing using %d. This will have the effect of casting the input value to an integer (as far as I'm aware, someone correct me if not) so you will always have an integer. Scanf is in a class of functions that arn't 'type safe'. From my understanding you will attempt to read into a memory block with the expected size with something that could up being larger so you'll have an undefined behaviour.

    If you have a range how abot something like this:
    int getInt(void)
    {
    	int z;
    	
    	do
    	{
    		printf("Please enter an integer\n");
    		scanf("%d",&z);
    	} while (z < 0 || z > 100);
    
    	return z;
    }
    

    Don't know if this is much help to you or not but I must get back to study :(....


  • Registered Users Posts: 1,996 ✭✭✭lynchie


    I was trying to assign it a vriable by using the scanf. But for some reason its not running that piece of code, I am at a loss.

    I tried scanResult is equal to the scanf in the code but it still wont let me input anything. Any ideas?

    You need to read the link I provided in an earlier post above which deals with scanf and reading from the buffer.

    Quite simply.. your loops is not working because after the first scanf, there is a carriage return in the buffer, so when the second loop beings, scanf returns 0 without asking for input because it already has 1 character in the input buffer, attempts to cast it to %d which fails and it returns 0 as the number of conversion's done. The loop continues indefinitely..


Advertisement