How to make sentinel loop disregard -1

i have a program where i need to know the average of a string of numbers. the user inputs their numbers and enters -1 to submit the numbers, but when it calculates the average it also uses the -1, how do i make it disregard the -1?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int main ()
{
	double value,  high= 0, low= 0, average, count=0,total=0;
	char again= 'y';

	cout << "Enter a series of positive numbers (-1 when done) : " << endl;
	cin >> value;

	while (value != -1)
	{
		if (value > high)
			high=value;
		
		
		if (count !=0)
		average=(total) / count;

		if (count > low)
			low=count;

		total=total+value;
		count++;
		cin>> value;
		
	}
	cout << " The high value is " << high << endl;
	cout << " The low value is " << low << endl;
	cout << " The average is " << setprecision (2) << fixed << average << endl;
1
2
3
4
if(value != -1)
{
  // stuff that will only be done if the value isn't -1
}
Well no, i need to enter a -1 to submit the users input. but when it calculates the average it is also adding the -1, i want it to only recognize -1 as the submit, not part of calculating the average
but when it calculates the average it is also adding the -1,


If value is -1, does the body of the while loop execute?
No it ends the loop when i enter -1 and then outputs what i have after the loop
If the body of the loop doesn't execute, how does it end up affecting the average when value is -1?
No, for the series of numbers to be submitted into the loop and to execute it you need to enter -1


Like if i wanted: 2, 4, 5,98 to be input i would need to put -1 at the end of that string of numbers to enter it. so when i want to have the average of all those numbers but without taking the -1 into account.
I'm perfectly aware of what a sentinel value does. My question is still: If the body of the loop doesn't execute when value is -1, how does it end up affecting the average?

What output would you expect for the input seqence 2 -1? What output do you get if you actually use that sequence when you run it?
Well the body of the loop does execute. it only stops when i enter -1
You are overcomplicating things.

Well no, i need to enter a -1 to submit the users input. but when it calculates the average it is also adding the -1


Right. So since you dont' want the averaging code to execute when value == -1, put that code in an if block.

1
2
3
4
5
6
7
8
9
while( value != -1 )
{
  value = get_from_user();

  if(value != -1)
  {
    // this code will not execute if value is -1
  }
}


Alternatively you could break out of the loop:

1
2
3
4
5
6
7
8
9
while( true )
{
  value = ...;

  if( value == -1 )
    break;

  // ...
}
The best way would probably be to just end the loop at a negative number and then perform calculations.

1
2
3
4
5
6
7
8
9
10
11
12
13

cin >> value;

while(value >= 0)
{
     total += value;
     count++;
     cin >> value;
}

average = total / count;

cout << . . .;


Just add in high and low where it fits in the loop. Also, I'm assuming you don't need negative numbers in your average.
The best way would probably be to just end the loop at a negative number and then perform calculations.


I've seen other people recommend that approach as well.

Personally I never liked it because you have to duplicate code (in this case, get the input twice)

I prefer the break approach, personally. But a lot of people flip out over that because using break is "bad".

But yeah there are lots of options.
Well, the OP was asking the wrong question. I could look at the code and see that obviously average was not being affected by the sentinel value, so I didn't feel a need to test the code. When I did take a closer look...

First average is never initialized. When you enter your first value as -1 you are treated to some trash output. (You're treated to the same display when you only enter 1 value and then the sentinel because of a bug in the body of the loop.)

Second, in order for the average to be calculated correctly, the count and total variables must be updated before the average. This doesn't happen on either account.

Third, the low variable was being compared to and assigned the value of count instead of value.

I would suggest initializing average to 0 and changing the loop to:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
	while (value != -1)
	{
		++count ;
		total+= value ;

		average = total/count ;

		if (value > high)
			high=value;
				
		if (value < low)
			low=value;

		cin>> value;
		
	}
Last edited on
I agree with GRex2595. Fill a buffer with all the values until less than zero (negative). Then do all the calculation from the values in the buffer. Or do the while loop test on >= 0 instead of test for -1. What if it's -2???
Here is a simple way to do it. Maybe it can give some idea's.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.H>
#include <string.h>
#include <conio.h>

int  iCnt;
int  iSize;
int  iTotal;
// Test values
int sBuffer[] = {2,5,7,4,8,9,2,6,-1};
int iMin;
int iMax;
int iAverage;


void main()

{
    iCnt  = 0;
    iSize = 1;
    iTotal = 0;
    iMin  = 10; // Set the maximum value;
    iMax  = 0;  // Set the minimum value

    while (sBuffer[iCnt] >= 0) {

        iTotal = iTotal + sBuffer[iCnt];

        if (sBuffer[iCnt] < iMin) {
            iMin = sBuffer[iCnt];
        }

        if (sBuffer[iCnt] > iMax) {
            iMax = sBuffer[iCnt];
        }
        iCnt++;
        iSize++;
    }

    iAverage = iTotal / iSize;

    cprintf("Minimum = %d\r\n", iMin);
    cprintf("Maximum = %d\r\n", iMax);
    cprintf("Average = %d\r\n", iAverage);

   // wait for keypress
    getch();
}
Ups... Forgot to increment iTotal.

1
2
3
        iCnt++;
        iSize++;
        iTotal++;


Do not increment iTotal. Everything is done in iTotal = iTotal + sBuffer[iCnt].
iSize should be defaulted to 0 and not to 1.
Last edited on
Cire, thanks a lot your post was a huge help!
i can get high and average to do what i want, however the low is now always displayed as the same as High

There was a typo when I posted it that I corrected immediately after. Check that the line reading if (value < low) isn't using >.
Got the thing to work, thanks for all your help!
Topic archived. No new replies allowed.