-
Code Error
Hello, I posted a while back, but it's been a while. I have learned a lot more, but ran into a problem today. I've been using a self teaching guide, and it gives you problems at the end of each chapter. Here is the problem I am working on:
3: Write a program that reads integers until 0 is entered. After input terminates, the program should report the total number of even integers (excluding the 0) entered, the average value of the even integers, the total number of odd integers entered, and the average value of the odd integers.
The program works, unless I enter a character. I know that C will store the character as a number, but do you know of a solution for this? Also, I can't use float type because of the % operand. What do you think?
Code:
#include<stdio.h>
#include<ctype.h>
#define EVEN 2
int main(void) {
int num;
int even, even_avg, odd, odd_avg;
even = even_avg = odd = odd_avg = 0;
printf("Enter some integers. Enter 0 to finish.\n");
while (scanf("%d", &num) == 1) {
/*if (isalpha(num)) {
printf("Invalid Entry. Please try again. %d\n", num);
continue;
}*/
if (num == 0)
break;
if ((num % EVEN) == 0) {
even++;
even_avg += num;
}
else {
odd++;
odd_avg += num;
}
}
printf("You have %d even %s, averaging %d.\n",
even, (even == 1) ? "number" : "numbers", even_avg / even);
printf("You have %d odd %s, averaging %d.\n",
odd, (odd == 1) ? "number" : "numbers", odd_avg/odd);
return 0;
}
It compiles fine. I use Cygwin and the compile it like this:
Code:
gcc -Wall -Werror -o file file.c
-
Your while loop is not supposed to have anything to do with the return value of scanf -- your while loop is supposed to run until the answer is 0.
If you want to deal with people typing in garbage, then you can't use scanf. You'll have to take a line of input with fgets, into a string, and then look at the string and see what you get.
-
Thanks for the fast reply, but I haven't learned fgets yet though. is there another way?
The loop breaks when 0 is entered.
-
Well, yes, the loop breaks when 0 is entered because you have a break there, not because of the while loop.
Right now your program should stop on illegal entry (either a or 5.6), because the return of scanf would be 0 (in the 5.6 example, it would read the 5 just fine, but stop on the .6 part). That's probably the best you can do without learning something.
-
Ah, well I guess I didn't follow the question exactly. It's not for a class or anything. I just want it to work. I know you have no idea what I have learned so far, but I don't see another way to set it up without the break statement. The chapter was about break and continue among other things, so that came to me first.
However, it doesn't stop on character input. it gives me this error:
Code:
5 [main] even_odd 5992 _cygtls::handle_exceptions: Error while dumping state <probably corrupted stack>
Segmentation fault <core dumped>
I assume it's a cygwin specific error. Did you try to compile it? Do you recommend any simple compilers of C? Something like gcc?
-
Why yes I have, using gcc in fact, though not in cygwin.
Code:
$ ./temp
Enter some integers. Enter 0 to finish.
17
18
29
35
6.5
You have 2 even numbers, averaging 12.
You have 3 odd numbers, averaging 27.
-
Can I assume you don't use windows then?
So it just truncates the number and breaks from the loop.I guess I need another way to figure out if the number is even or odd than using %.
What did you get typing a character? thanks for the testing :p
-
ah, so the .5 isnt even processed until the next time around. the 6 makes it through the loop. I didn't know it did that!
-
Using gcc on windows (MinGW, not cygwin):
Code:
>temp
Enter some integers. Enter 0 to finish.
17
18
19
35
6.5
You have two even numbers, averaging 12.
You have three odd numbers, averaging 23.
Since 6.5 is neither even nor odd, I don't know what you plan to do with the input if you get it.
Edit: And characters just stop the same way.
-
I think this pretty much fixes everything :)
Code:
#include<ctype.h>
#define EVEN 2
int main(void) {
float num;
int even, odd;
float even_avg, odd_avg;
even = even_avg = odd = odd_avg = 0;
printf("Enter some integers. Enter 0 to finish.\n");
while (scanf("%f", &num) == 1) {
if (num == 0)
break;
if (((int) num % EVEN) == 0) {
even++;
even_avg += num;
}
else {
odd++;
odd_avg += num;
}
}
printf("You have %d even %s, averaging %f.\n",
even, (even == 1) ? "number" : "numbers", even_avg / even);
printf("You have %d odd %s, averaging %f.\n",
odd, (odd == 1) ? "number" : "numbers", odd_avg/odd);
return 0;
}
-
or maybe not, but it's a step in the right direction lol
i guess 6.3 would still be an even number huh...damn
-
i will try a different approach and post again later.
-
Well, if your program deals with INTEGER values, then reading floating point values as correct input is not the right solution.
Is part of your assignment to make the input "tolerant" to erroneous input? If that is not the case, I'd leave it reading with scanf using the "%d" format specifier and an integer variable - because that will do the right thing for correct input.
Dealing with incorrect input is pretty tricky, and the code you need to do that properly requires a bit more than what you currently know. It's good to be aware of these things, but unless it's actually part of the assignment [in which case you should have been told how to use for example fgets()], then I'm sure you will get full marks with a scanf("%d"...)
--
Mats
-
I think you are right. It's not for a class, so I dont have to worry about marks. fgets() is chapter 13 and im on chapter 7, so I think this would be good enough for what I know. It asks me to redo it using switch, but I think the problem remains the same. Thanks both of you for the help.