0

I'm trying to make a small program, where user enters a list of numbers and at the end it shows how much in % of the numbers are odd or even.

If the user enters no value (just presses enter) it stops request a number and shows the calculation, but if the user enters exit it exits. Additionally I want to check if the entered number is a whole number.

Here what I got so far:

    #include <stdio.h>

int main(void)
{
    int input, all [100], even[100], odd[100], even_counter, even_print, odd_counter, odd_print, total_counter, total_print, even_p, odd_p;
    char cinput;
    for (;;)
    {
        printf("Enter a number: ");
        if (scanf("%d", &cinput) != 1) break;
        input=(int)(cinput-0);
        all[total_counter]=input; //Insert number in all numbers array

        if (input % 2 == 0)
        {
            even[even_counter]=input; //Insert number in even numbers array
            even_counter++;
            total_counter++;
        }
        if (input % 2 != 0)
        {
            odd[odd_counter]=input; //Insert number in odd numbers array
            odd_counter++;
            total_counter++;
        }
    }

    printf("\n You entered the following numbers: ");
    for (total_print=0; total_print<total_counter; total_print++)
    {
        printf("%d ", all[total_print]); //Show all entered numbers
    }
    printf("\n Even numbers are: ");
    for (even_print=0; even_print<even_counter; even_print++)
    {
        printf("%d ", even[even_print]); //Show even numbers only
    }
    printf("\n Odd numbers are: ");
    for (odd_print=0; odd_print<odd_counter; odd_print++)
    {
        printf("%d ", odd[odd_print]); //show odd numbers only
    }

    printf("\n\n Total numbers entered: %d", total_counter); //Show count of all numbers
    printf("\n Even numbers entered: %d", even_counter); //Show count of even numbers
    printf("\n Odd numbers entered: %d", odd_counter); //Show count of odd numbers

    even_p=(even_counter/total_counter)*100; //Calculate % of even numbers
    odd_p=(odd_counter/total_counter)*100; //Calculate % of odd numbers

    printf("\n\n Even numbers are %d %% of total number (%d out of %d)", even_p, even_counter, total_counter);
    printf("\n Odd numbers are %d %% of total number (%d out of %d)", odd_p, odd_counter, total_counter);
}

What works:

  • It saves all entered numbers in one array, even and odd numbers in separate arrays.
  • It counts how many numbers were entered, how many are even and how many are odd.
  • As soon as a non-numeric character is entered it goes to showing the result.

What doesn't work:

  • The % calculation always says that it's 0%.
  • The first number in the odd array is 0.

What I can't figure out:

  • How to make it go to the results if nothing is entered? Tried if (scanf("%d", &cinput) != "\n") break;, but it just got stuck in the loop request another number.
  • How to make the program exit if exit is entered?
  • How to check if a whole number is entered?

EDIT

Counters initialized. scanf("%d", &cinput) changed to scanf("%d", &input). Changed even_p and odd_p to float (from int). Now the calculation is working fine and the first value in odd_array is good to.

#include <stdio.h>

int main(void)
{
    int input, all [100], even[100], odd[100], even_counter, even_print, odd_counter, odd_print, total_counter, total_print;

    even_counter=0;
    even_print=0;
    odd_counter=0;
    odd_print=0;
    total_counter=0;
    total_print=0;
    for (;;)
    {

        printf("Enter a number: ");
        if (scanf("%d", &input) != 1) break;
        all[total_counter]=input; //Insert number in all numbers array

        if (input % 2 == 0)
        {
            even[even_counter]=input; //Insert number in even numbers array
            even_counter++;
            total_counter++;
        }
        if (input % 2 != 0)
        {
            odd[odd_counter]=input; //Insert number in odd numbers array
            odd_counter++;
            total_counter++;
        }
    }

    printf("\n You entered the following numbers: ");
    for (total_print=0; total_print<total_counter; total_print++)
    {
        printf("%d ", all[total_print]); //Show all entered numbers
    }
    printf("\n Even numbers are: ");
    for (even_print=0; even_print<even_counter; even_print++)
    {
        printf("%d ", even[even_print]); //Show even numbers only
    }
    printf("\n Odd numbers are: ");
    for (odd_print=0; odd_print<odd_counter; odd_print++)
    {
        printf("%d ", odd[odd_print]); //show odd numbers only
    }

    printf("\n\n Total numbers entered: %d", total_counter); //Show count of all numbers
    printf("\n Even numbers entered: %d", even_counter); //Show count of even numbers
    printf("\n Odd numbers entered: %d", odd_counter); //Show count of odd numbers

    float even_p=((float)(even_counter)/total_counter)*100; //Calculate % of even numbers
    float odd_p=((float)(odd_counter)/total_counter)*100; //Calculate % of odd numbers

    printf("\n\n Even numbers are %f %% of total number (%d out of %d)", even_p, even_counter, total_counter);
    printf("\n Odd numbers are %f %% of total number (%d out of %d)", odd_p, odd_counter, total_counter);
}

Now I just need the input to be checked if it's a whole number (display a message, but continue to ask for numbers), go to calculation if no value is entered, quit if exit is entered. And I forgot - the user should not be able to go to calculation if he enters less than 10 numbers. :(

  • You should scan a string and parse it according to your needs [helpful link](http://stackoverflow.com/questions/5406935/reading-a-string-with-scanf) – Sebastian L Apr 05 '17 at 10:14
  • 'if (scanf("%d", &cinput) != 1)' no. cinput is a char, you read an int:( – ThingyWotsit Apr 05 '17 at 10:31
  • You should initialize the counters to 0. – Ian Abbott Apr 05 '17 at 10:46
  • Counters initialized. `scanf("%d", &cinput)` changed to `scanf("%d", &input)`. Changed `even_p` and `odd_p` to `float` (from `int`). Now the calculation is working fine and the first value in `odd_array` is good to. Now any tips how to check if entered value is a whole number, break the loop if `\n` is entered and quit if `exit` is entered? – Karalis Artūrs Apr 05 '17 at 10:49

3 Answers3

1
even_p=(even_counter/total_counter)*100;

The above preforms integer division. You don't get an exact divisor, but the the integer immediately preceding it. Since even_counter is always less than total_counter you get zero.

A simple fix is to multiply first, and divide second:

even_p = even_counter * 100 / total_counter;

But your program has undefined behavior all around regardless. You don't initialize all of your variables. For instance, odd_counter isn't initialized, and yet you confidently read its value here:

    if (input % 2 != 0)
    {
        odd[odd_counter]=input; //Insert number in odd numbers array
        odd_counter++;
        total_counter++;
    }

The things you can't figure out can fill a post on their own. It's all about parsing. You need to read an entire line (say with fgets) and then try to parse it (for instance, with repeated applications of sscanf).

StoryTeller - Unslander Monica
  • 148,497
  • 21
  • 320
  • 399
  • odd_counter is initialized at the beginning Changed even_p and odd_p to float and it worked. – Karalis Artūrs Apr 05 '17 at 10:23
  • @KaralisArtūrs - No it isn't. It's declared, without any initialization. – StoryTeller - Unslander Monica Apr 05 '17 at 10:24
  • Ok. So I changed int input, all [100], even[100], odd[100], even_counter=0, even_print=0, odd_counter=0, odd_print=0, total_counter=0, total_print=0; But even without initializing the % calculation worked when I changed it even_p and odd_p to float. That leaves just the "Why is the first value in odd_array always a 0?" – Karalis Artūrs Apr 05 '17 at 10:32
  • @KaralisArtūrs - hold on. This is also a big no no `scanf("%d", &cinput)`. Conversion specifiers *must match* the types of the variables. Or the behavior of your program is undefined. Compile with all warnings enabled. And better yet, have the compiler treat them like errors, so you'd be forced to address them. – StoryTeller - Unslander Monica Apr 05 '17 at 10:36
  • Originally it was `scanf("%d", &input)` but that would not work if I want the user to be able to enter "exit" to quit the program. – Karalis Artūrs Apr 05 '17 at 10:44
  • @KaralisArtūrs What makes you think `scanf("%d", &cinput);` would work? And `scanf("%d", &input);` would return 0 if you entered "exit". – Ian Abbott Apr 05 '17 at 10:50
  • I'm a complete beginner here. When I changed `&input` to `&cinput` I just forgot to change `"%d"` to `"%s"`. – Karalis Artūrs Apr 05 '17 at 11:07
1

There are several issues in the code.

First, your variables, especially odd_counter and so on are not initialised. Hence, an expression like odd[odd_counter]=input yields undefined behaviour (and actually you have a good chance that the program crashes). Note that in C local variables of integral type are NOT by default initialized, neither with 0 nor with any other value. So you need to write int odd_counter=0, even_counter=0, ... and so on. Otherwise your program might yield a correct output (as a correct output is one of thousands of possible outputs due to undefined behaviour), but it is for sure not guaranteed.

Second, even_p=(even_counter/total_counter)*100 performs an integer division (nothing behind the comma), so even_counter/total_counter will always be 0 if total_counter is greater than even_counter. So you could write even_p=((even_counter*100)/total_counter), or (((float)even_counter)/total_counter)*100. Decide if even_p should be float or double as well.

Third, you use %d (i.e. int) to scan into a variable of type signed char. Use scanf("%hhd", &cinput) instead; Format specifier %d together with length sub-specifier hh tells scanf to scan a numerical value into a signed char target (confer printf/scanf reference). Or: change type of variable cinput to int.

After fixing all these issues, the topic "Why is the first value in odd_array always a 0" should be solved as well.

Stephan Lechner
  • 33,675
  • 4
  • 27
  • 49
0

You declare

    char cinput;

and then use it in

    scanf("%d", &cinput)

That's bad, very bad... Format specifier "%d" expects a pointer to int as a corresponding parameter, not a pointer to char. And int is longer than char (typically 4 vs. 1 byte), so the input value gets stored outside the destination cinput variable.

What happens next is Undefined Behavior.

CiaPan
  • 8,142
  • 2
  • 18
  • 32