helping program an average program in C

Started by
9 comments, last by Zahlman 17 years, 5 months ago
Hey all. My c is a little rusty and I've been trying to help somebody with an average program they are making. The point is to take in a grade: A, B, C, D, or F. Then once that is done it will ask for the value of that grade. The program needs to loop and keep asking for the grade/grade value combo until the user puts something other than an A, B, C, D, or F in. I came up with this short program:


#include <stdio.h>
    
    
     int main (void)
     {
         char answer;
         int value;
         int counter = 0;
         int total = 0;
         float sum;
         
         printf("Enter your grade \n");
         scanf("%c", &answer);
      
         
         while (answer = 'A' || 'a' || 'B' || 'b' || 'C' || 'c' ||
                          'D' || 'd' || 'F' || 'f') {
         
           printf("Enter grade value \n");
           scanf("%d", &value);
           
               sum = total + value;
               counter++;
               scanf("%d", &value);
             
               }
               
               printf("The GPA of the " +counter);
               printf("grades  is " + total/counter);
               }
              

It compiles but it doesn't terminate when the char is not a valid grade. I also don't think that it is looping right. If anybody has any ideas I would appreciate it. I haven't programed in c lately and my loops might be a little off.
Advertisement
you're not changing the value of answer anywhere inside your while loop. thus, it will never exit.

also, per loop, you're reading in 2 entries which means that when you fix the above, you'll now have a bug where the loop will only have the possibility for terminating on every other character entry.

-me
Do you know how to use a debugger? Step through your program and see what happens when you type in a non-letter.

As an asside, I would advise against writing code that is BOTH a condition and an assignment.

(Yes, I know what is wrong. But can figure it out too!)
answer will always equal 1 so that your while loop will never terminate.

while (answer = 'A' || 'a' and so on)

should be

while (answer == ('A' || 'a' and so on))

Edit: I put extra parenthesis cause I am rusty on the operator precedence.
Quote:Original post by Adam Hamilton
answer will always equal 1 so that your while loop will never terminate.

while (answer = 'A' || 'a' and so on)

should be

while (answer == ('A' || 'a' and so on))


what? no... not unless i've missed something fundimental. Each check needs to be it's own statement:

while (answer == 'A' || answer == 'a' || answer == 'B' ....

but anyway, as i point out, answer never changes so...

Yes, learn to use a debugger and thereby figure it out.

-me
Quote:

what? no... not unless i've missed something fundimental. Each check needs to be it's own statement:

while (answer == 'A' || answer == 'a' || answer == 'B' ....


I might also suggest that you precede the above with a statement like

answer = toupper (answer);

Then you can reduce the number of checks you need to do by half by doing the following:

while (answer == 'A' || answer == 'B' || answer == 'C'......)

Ŀ
I have wrote a program that works correctly, I can give you it if you want or do you want to solve the problem yourself?

The way you are going about it is all wrong try using a switch statement with a case for each letter.

for example;

switch(answer)
{
case 'a' :
}

I will post the code if you like let me know?
Using a switch statement for something where you'd expect an if statement can
have readability issues. (I'd also expect many compilers to implement the switch
via an if statement, rather than a computed jump.)

#include <string.h>

if(!strchr("AaBbCcDdEeFf",answer)) break;

The fastest way is probably a (non-portable) character range comparision - it'll probably screw up if you're not using ASCII (or by extension the ASCII subset of UTF8), of course.

if((answer<'A' || answer>'F') && (answer<'a' || answer>'f')) break;

Speaking of Unicode, there's a number of things that would be problematic for
programs that didn't use the (Unicode) standard library functions (in this case wstrchr) for example, where some sequences of codepoints are equivalent to some codepoints...but I digress.


-- Jonathan
This is the code that I have written hopw it helps.

int grade_value(int total);

int main()
{
char answer;
int counter = 0;
int total = 0;
int sum =0;
int valid = 1;


while(valid)
{
printf("Enter your grade \n");
scanf("%c", &answer);
getchar(); /*Gets the return key press*/

switch(answer)
{
case 'a' : sum = grade_value(sum);
counter++;
break;
case 'b' : sum = grade_value(sum);
counter++;
break;
case 'c' : sum = grade_value(sum);
counter++;
break;
case 'd' : sum = grade_value(sum);
counter++;
break;
case 'e' : sum = grade_value(sum);
counter++;
break;
case 'f' : sum = grade_value(sum);
counter++;
break;
default: printf("Invalid Grade Entered\n");
valid = 0;
break;
}
printf("The GPA of the %d grades is %d\n", counter, sum);
}


return (0);
}

int grade_value(int total)
{
int sum = 0, value = 0;

printf("Enter grade value \n");
scanf("%d", &value);
getchar();
sum = total + value;

return (sum);
}
Funny how code decreases in size as experience increases. :)

markShires, as you can see, it can be done with a single, short if statement. More importantly, LucidIon's if statements express far better what is being done, while a switch statement isn't really appropriate here - there's just two different situations (a grade or not a grade) and the cases that map to these situations are a continuous range.

Oh, and just in case you do want to stick to that switch statement, you can leave out the

sum = grade_value(sum);
counter++;
break;

lines for all but the last correct grade case. That way the switch will fall through to those two lines if it's a correct grade. Not a very clean approach though. :)
Create-ivity - a game development blog Mouseover for more information.

This topic is closed to new replies.

Advertisement