Jump to content

C if statement help

SgtBot

Hi,

 

I had a homework assignment due a few months ago that i got a mostly good grade on, however there was one problem with my code. It would never count the first negative number I entered, but it would count all the ones after that. I'm not sure how to fix this, and I didn't get any feedback from my instructor. Here is the code:

 

#include<stdio.h>

main()
{
    int user_input = 0;

    int total_sum = 0;
    int positive_sum = 0;
    int negative_sum = 0;
    int nonzero_count = 0;
    int positive_count = 0;
    int negative_count = 0;
    int largest = 0;
    int smallest = 0;
    int largest_positive = -65535;
    int smallest_positive = 65535;
    int largest_negative = -65535;
    int smallest_negative = 65535;
    float average = 0;
    float average_positive = 0;
    float average_negative = 0;

    printf("Enter an integer:\n");
    scanf("%d", &user_input);

    while(user_input != 0)
    {
        nonzero_count++;
        total_sum = total_sum + user_input;
        average = (float)total_sum/(float)nonzero_count;
        
        if(user_input > largest)
            largest = user_input;
        if(user_input < smallest)
            smallest = user_input;

        printf("Enter an integer:\n");
        scanf("%d", &user_input);

        if(user_input > 0)
        {
            positive_count++;
            positive_sum = positive_sum + user_input;
            average_positive = (float)positive_sum/(float)positive_count;
        
            if(user_input > largest_positive)
            {
                largest_positive = user_input;
            }
            if(user_input < smallest_positive)
            {    
                smallest_positive = user_input;
            }
        }
        
        else if(user_input < 0)
        {
            negative_count++;
            negative_sum = negative_sum + user_input;
            average_negative = (float)negative_sum/(float)negative_count;

            if(user_input > largest_negative)
            {
                largest_negative = user_input;
            }
            if(user_input < smallest_negative)
            {
                smallest_negative = user_input;
            }
        }
    }
    printf("Overall:\n");
    printf("Count is %d, sum is %d, maximum is %d, minimum is %d, average is %f\n\n", nonzero_count, total_sum, largest, smallest, average);

    printf("Positives:\n");
    printf("Count is %d, sum is %d, maximum is %d, minimum is %d, average is %f\n\n", positive_count, positive_sum, largest_positive, smallest_positive, average_positive);

    printf("Negatives:\n");
    printf("Count is %d, sum is %d, maximum is %d, minimum is %d, average is %f\n\n", negative_count, negative_sum, largest_negative, smallest_negative, average_negative);
}

My problem happens when trying to do the math on counting the number of negative numbers. It will always ignore the first negative number but count the rest, except in the overall counter.

Here is an example of what I'm talking about:

image.png.67eaafdc7cd91c7a50133c6f2cd302d3.png

And with an extra negative number:

image.png.6bd29afe2b6246d0fb259e83544ed8e5.png

Here it is with the full set of numbers I was instructed to use:

image.png.d6408e20c328616b1d991898890b7caa.png

I'm not sure if it's a problem with the placement or types of my if statements, but it's the only thing I can think of that would affect whether a number would get evaluated in the loop. Any advice would be greatly appreciated!

 

Thanks!

 

EDIT:

To be more exact about the problem, the sum, maximum and minimum, and average seem to be working as intended in the negative loop, the only thing that is working incorrectly is the counting in the negative loop. It will count all of the negative numbers except the first one entered.

Link to comment
Share on other sites

Link to post
Share on other sites

move the 

nonzero_count++;

to the end of the while loop as your adding 1 to it immediately, so e.g you start nonzero_count at 0 outside the while loop the first number you will be testing from it will be 1 as your immediately adding that 1 to it. 

The owner of "too many" computers, called

The Lord of all Toasters (1920X 1080ti 32GB)

The Toasted Controller (i5 4670, R9 380, 24GB)

The Semi Portable Toastie machine (i7 3612QM (was an i3) intel HD 4000 16GB)'

Bread and Butter Pudding (i7 7700HQ, 1050ti, 16GB)

Pinoutbutter Sandwhich (raspberry pi 3 B)

The Portable Slice of Bread (N270, HAHAHA, 2GB)

Muffinator (C2D E6600, Geforce 8400, 6GB, 8X2TB HDD)

Toastbuster (WIP, should be cool)

loaf and let dough (A printer that doesn't print black ink)

The Cheese Toastie (C2D (of some sort), GTX 760, 3GB, win XP gaming machine)

The Toaster (C2D, intel HD, 4GB, 2X1TB NAS)

Matter of Loaf and death (some old shitty AMD laptop)

windybread (4X E5470, intel HD, 32GB ECC) (use coming soon, maybe)

And more, several more

Link to comment
Share on other sites

Link to post
Share on other sites

Your problem is not that you're not counting negative numbers, but you're not counting the last number entered:

Enter an integer:
1
Enter an integer:
1
Enter an integer:
0
Overall:
Count is 2, sum is 2, maximum is 1, minimum is 0, average is 1.000000

Positives:
Count is 1, sum is 1, maximum is 1, minimum is 1, average is 1.000000

Negatives:
Count is 0, sum is 0, maximum is -65535, minimum is 65535, average is 0.000000

Take a close look at when you do the counting.

Link to comment
Share on other sites

Link to post
Share on other sites

3 minutes ago, grimreeper132 said:

move the 


nonzero_count++;

to the end of the while loop as your adding 1 to it immediately, so e.g you start nonzero_count at 0 outside the while loop the first number you will be testing from it will be 1 as your immediately adding that 1 to it. 

I just tried that, but I might be misunderstanding what you are trying to say...

Here is the code that I tried after your instruction:

image.png.1de2d43490ac8bedef5611be21a4c3b9.png

I moved the nonzero_count to the end of the while statement but I am still getting the same issue

Link to comment
Share on other sites

Link to post
Share on other sites

5 minutes ago, zhick said:

Your problem is not that you're not counting negative numbers, but you're not counting the last number entered:


Enter an integer:
1
Enter an integer:
1
Enter an integer:
0
Overall:
Count is 2, sum is 2, maximum is 1, minimum is 0, average is 1.000000

Positives:
Count is 1, sum is 1, maximum is 1, minimum is 1, average is 1.000000

Negatives:
Count is 0, sum is 0, maximum is -65535, minimum is 65535, average is 0.000000

Take a close look at when you do the counting.

Are you sure its not counting the last number? 0 is supposed to terminate the loop, so it isn't supposed to count that... in this screenshot you can see I use the numbers 1 and 2, and it counts only 1 for positive numbers when the result should be 2, and it does not recognize 1 as the smallest. I thought it was only a problem with the negatives but I'm not so sure now. It correctly gets the total sum as 3, but only in the overall lines, in the positive if loop it still only counts the number 2, and not the number 1

EDIT: forgot to add screenshot

image.png.8085a3a77e353cfbe340e78a5759fcce.png

Link to comment
Share on other sites

Link to post
Share on other sites

Again:

7 minutes ago, zhick said:

Take a close look at when you do the counting.

To be more precise: Which number are you using to decide whether a number is negative or positive?

Link to comment
Share on other sites

Link to post
Share on other sites

7 minutes ago, zhick said:

Again:

To be more precise: Which number are you using to decide whether a number is negative or positive?

I'm using the number 0...

So from my understanding:
 

if(number < 0)
    count++;

And say for example I pass the number 3 through the loop. The compiler should take the number -3 and ask

if(-3 < 0)
   count++;

Since -3 is lower than 0, the variable count should be increased by 1. I'm not sure why I would need to use a different number besides 0 to check whether the integer is negative or positive... is there a thing with C where it treats 0 differently? Or maybe I'm just misunderstanding you...

Link to comment
Share on other sites

Link to post
Share on other sites

8 minutes ago, SgtBot said:

Or maybe I'm just misunderstanding you...

Yeah, maybe I could've worded that better. What's the value of the variable you're comparing to zero (don't worry, that part is correct) at that point in the program?

Btw, I don't mean to lead you on, so if you'd prefer me to just tell you the solution just say so. I just think it's better to point someone in the right direction and let them figure out the rest of the way themselves.

Link to comment
Share on other sites

Link to post
Share on other sites

Look here:

printf("Enter an integer:\n");
scanf("%d", &user_input);

while(user_input != 0)
{
        nonzero_count++;
        total_sum = total_sum + user_input;
        average = (float)total_sum/(float)nonzero_count;
        
        if(user_input > largest)
            largest = user_input;
        if(user_input < smallest)
            smallest = user_input;

        printf("Enter an integer:\n");
        scanf("%d", &user_input);

 

[Out-of-date] Want to learn how to make your own custom Windows 10 image?

 

Desktop: AMD R9 3900X | ASUS ROG Strix X570-F | Radeon RX 5700 XT | EVGA GTX 1080 SC | 32GB Trident Z Neo 3600MHz | 1TB 970 EVO | 256GB 840 EVO | 960GB Corsair Force LE | EVGA G2 850W | Phanteks P400S

Laptop: Intel M-5Y10c | Intel HD Graphics | 8GB RAM | 250GB Micron SSD | Asus UX305FA

Server 01: Intel Xeon D 1541 | ASRock Rack D1541D4I-2L2T | 32GB Hynix ECC DDR4 | 4x8TB Western Digital HDDs | 32TB Raw 16TB Usable

Server 02: Intel i7 7700K | Gigabye Z170N Gaming5 | 16GB Trident Z 3200MHz

Link to comment
Share on other sites

Link to post
Share on other sites

its because you are setting the user_input just before the dowhile then resetting it again before you hit your IF statment. this means the first entered amount will do the first part of the do while but never get to your if statments.

 

    printf("Enter an integer:\n");
    scanf("%d", &user_input);

    while(user_input != 0)
    {
        nonzero_count++;
        total_sum = total_sum + user_input;
        average = (float)total_sum/(float)nonzero_count;
        
        if(user_input > largest)
            largest = user_input;
        if(user_input < smallest)
            smallest = user_input;



        if(user_input > 0)
        {
            positive_count++;
            positive_sum = positive_sum + user_input;
            average_positive = (float)positive_sum/(float)positive_count;
        
            if(user_input > largest_positive)
            {
                largest_positive = user_input;
            }
            if(user_input < smallest_positive)
            {    
                smallest_positive = user_input;
            }
        }
        
        else if(user_input < 0)
        {
            negative_count++;
            negative_sum = negative_sum + user_input;
            average_negative = (float)negative_sum/(float)negative_count;

            if(user_input > largest_negative)
            {
                largest_negative = user_input;
            }
            if(user_input < smallest_negative)
            {
                smallest_negative = user_input;
            }       
        }
    printf("Enter an integer:\n"); 
    scanf("%d", &user_input);
    }
Link to comment
Share on other sites

Link to post
Share on other sites

Just now, zhick said:

Yeah, maybe I could've worded that better. What's the value of the variable you're comparing to zero (which is correct) at that point in the program?

Btw, I don't mean to lead you on, so if you'd prefer me to just tell you the solution just say so. I just think it's better to point someone in the right direction and let them figure out the rest of the way themselves.

No I appreciate you not just telling me, I think I will learn better from learning how to troubleshoot code. But I think I understand.

I had the

printf("Enter an integer:\n");
scanf("%d", &user_input);

in the while loop before the if statements in the loop actually started. So after it did the counting for the overall variables, which were done correctly, it would grab a different value for user_input from the user in the middle of the loop before the first value could be ran through the if statements.

image.png.a9f4f116e9e48fc82a361523e5dcd713.png

So it would never count the first value you enter at the beginning of the loop because it gets overwritten halfway through.. am I correct?

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, link-omthsed said:

its because you are setting the user_input just before the dowhile then resetting it again before you hit your IF statment. this means the first entered amount will do the first part of the do while but never get to your if statments.

Yeah I just realized that, thank you though!

Link to comment
Share on other sites

Link to post
Share on other sites

yep you got it :) other persons comment was better as you learnt from it i'm not a good teacher i just like to answer.

Link to comment
Share on other sites

Link to post
Share on other sites

Just now, link-omthsed said:

yep you got it :) other persons comment was better as you learnt from it i'm not a good teacher i just like to answer.

No problem, either way it was a very simple and understandable mistake, I just kept thinking it was a problem with the loops themselves :)

Link to comment
Share on other sites

Link to post
Share on other sites

Maybe to expand on this a little bit:

Yes, this is a very simple mistake, but mistakes of this kind are quite common and stem from doing "the same thing" at two different points, which makes it easy to mess up.

In this case you could restructure your program to make it so the input is only always read at one point:

Instead of

int user_input = 0;

// ...

printf("Enter an integer:\n");
scanf("%d", &user_input);

while(user_input != 0)
{
// ...
	printf("Enter an integer:\n");
	scanf("%d", &user_input);
// ...
}

You could just have this as

do 
{
  int user_input = 0;
  printf("Enter an integer:\n");
  scanf("%d", &user_input);
  
  if (user_input == 0)
    exit;
// ..
} while (1)

This way it's always clear when input is read (only ever at the beginning of the loop) and when it's processed.

Link to comment
Share on other sites

Link to post
Share on other sites

5 minutes ago, zhick said:

Maybe to expand on this a little bit:

Yes, this is a very simple mistake, but mistakes of this kind are quite common and stem from doing "the same thing" at two different points, which makes it easy to mess up.

In this case you could restructure your program to make it so the input is only always read at one point:

Instead of


int user_input = 0;

// ...

printf("Enter an integer:\n");
scanf("%d", &user_input);

while(user_input != 0)
{
// ...
	printf("Enter an integer:\n");
	scanf("%d", &user_input);
// ...
}

You could just have this as


do 
{
  int user_input = 0;
  printf("Enter an integer:\n");
  scanf("%d", &user_input);
  
  if (user_input == 0)
    exit;
// ..
} while (1)

 

Oh that would have made it a lost easier in the first place! I messed around with do while before but I haven't really used it in any homework yet as I'm more comfortable with the normal while loops

Link to comment
Share on other sites

Link to post
Share on other sites

do-loops often get a bad rep, and not entirely without reason, as it can really become a mess if there's several exits or whatever scattered around in the loop body.

But in cases like this where it's basically just a while loop (condition is still checked right at the top of the loop) they can be quite handy.

Another, arguably even better approach is to keep the loop as a while-loop and just change the way input is read:

int read_int()
{
	int input = 0;
	printf("Enter an integer:\n");
	scanf("%d", &input);
	return input;
}

// ...

int user_input = 0;
while ((user_input = read_int()) != 0)
{
	// ...
}

Some oldschool c-folks will scream and shout that this is not optimal because of the extra function call, but any non-braindead compiler will optimize this out.

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, zhick said:

do-loops often get a bad rep, and not entirely without reason, as it can really become a mess if there's several exits or whatever scattered around in the loop body.

But in cases like this where it's basically just a while loop (condition is still checked right at the top of the loop) they can be quite handy.

Another, arguably even better approach is to keep the loop as a while-loop and just change the way input is read:


int read_int()
{
	int input = 0;
	printf("Enter an integer:\n");
	scanf("%d", &input);
	return input;
}

// ...

int user_input = 0;
while ((user_input = read_int()) != 0)
{
	// ...
}

Some oldschool c-folks will scream and shout that this is not optimal because of the extra function call, but any non-braindead compiler will optimize this out.

Haha well I'm not sure how the compiler for my class is but we are using the ANSI 90 version of C so it's pretty old xD Now I just have to finish my array assignment before tonight without using if statements and using only one variable besides arrays ¯\_(ツ)_/¯

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×