Thread: Finding simple min, max, mean in C

  1. #1
    Registered User
    Join Date
    Sep 2006
    Posts
    4

    Finding simple min, max, mean in C

    Hey I seem to be gotten stuck on a simple C problem. The program is supposed to ask user for a number, till EOF and then print out the highest, lowest and average statistic.
    I have something like this in the code:
    Buf is a char, and all this is inside a loop:
    Code:
    do {
    	input=atof(gets(buf));
    	max=min=sum=input;
    	count++;
    	if (input <= min){
    		input=min;}
    	if (input >= max){
    		input=max;}
        sum = sum + input;
    	
    	}
    	while (strlen(buf) > 0);
    Then i just print out the average(sum/count) and max and min.

    So if anybody can point me to a valid (but simple) solution that would be appreciated.

    Thanks..
    R.
    Last edited by rQQt; 09-18-2006 at 03:46 PM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    S'pose we'd better get the basics out of the way first
    http://cboard.cprogramming.com/showthread.php?t=25765

    And never use gets()
    http://faq.cprogramming.com/cgi-bin/...&id=1043284351

    I'm guessing there are 3 more lines in your program, so why not post all of them rather than leaving us to guess whether buf is a char* or not ?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    When I want the min or max of a series of items, I initialize them before the loop to "impossibly high" for min, and "impossibly low" for max:
    Code:
    min = 32356;
    max = -32356;
    sum = 0;
    
    / * Now do the do: */
    
    do  {
       get input
       /* you need to count the number of items input, so you can divide and get an average */
       numItems++
       if min > input 
         min = input
    
       if max < input
         max = input
      
       /* and sum is never assigned to any input. It's like this: */
       sum += input
       print min, max, sum/numItems
    
       if input == trigger  /* in your case, EOF */
          break
    }
    Adak

  4. #4
    The Richness... Richie T's Avatar
    Join Date
    Jan 2006
    Location
    Ireland
    Posts
    469
    >>When I want the min or max of a series of items, I initialize them before the loop to "impossibly high" for min, and "impossibly low" for max:

    I disagree with that logic - never assume that anything is impossibly large/small. I prefer to store the first value in the max (or min) variable, and compare all subsequent values to that value - if a value is bigger, it's the new max.

    I agree with Salem - post your whole code.
    No No's:
    fflush (stdin); gets (); void main ();


    Goodies:
    Example of fgets (); The FAQ, C/C++ Reference


    My Gear:
    OS - Windows XP
    IDE - MS Visual C++ 2008 Express Edition


    ASCII stupid question, get a stupid ANSI

  5. #5
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    I disagree with that logic - never assume that anything is impossibly large/small. I prefer to store the first value in the max (or min) variable
    Same here.

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    A counter point would be that it's actually easier to write the code if you initially set the max to the variable's lower bound, and the minimum to the variable's upper bound. You don't have to "special case" for the first read.


    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Quote Originally Posted by quzah
    A counter point would be that it's actually easier to write the code if you initially set the max to the variable's lower bound, and the minimum to the variable's upper bound. You don't have to "special case" for the first read.


    Quzah.
    True. It's too bad Adak's example doesn't do that.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    4

    followup

    Hey guys, thanks for your help. Unfortunately I'm still having trouble with the code. It only gives me the max, the min stays zero.
    Here's the complete code:
    Code:
    
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    
    char buf[BUFSIZ + 1];
    int count=0;
    float input,sum;
    min=32356;
    max=-32356;
    
    
    int main()
    {
        do {
    	printf("enter");
    	input=atof(gets(buf));
    	
    	count++;
    	
    	if (min > input)
    		min=input;
    	if (max < input)
    		max=input;
    		
           sum +=input;
    	
    	//diagnostics
    	printf("input%i\n",input);
    	printf("count%i\n",count);
    	printf("max%i\n",max);
    	printf("min%i\n",min);
    //
    	}
    		while (strlen(buf) > 0);
    
    	
    	printf("\ncount %i\n",count-1);
    	printf(" min %i\n",min);
    	printf("  max %i\n",max);
    	printf(" ave %f\n",(sum/(count-1)));
    	
    	
    
    
     
    	return (0);
    }
    The printf tells me that while it's in the loop the min max and ave are all right, but when it finishes, the min is allways 0.

    Here's the output:
    enter 2
    input 0
    count 1
    max 2
    min 2

    enter 5
    input 0
    count 2
    max 5
    min 2

    enter 2
    input 0
    count 3
    max 5
    min 2

    enter
    input0
    count4
    max5
    min0


    entered 3
    low 0
    high 5
    average 3.000000

    At this point the low should be 2,
    I'msure i'm making some stupid little mistake somewhere, it's just I don't know where..
    Last edited by rQQt; 09-20-2006 at 02:45 PM.

  9. #9
    The Richness... Richie T's Avatar
    Join Date
    Jan 2006
    Location
    Ireland
    Posts
    469
    >>I'msure i'm making some stupid little mistake somewhere, it's just I don't know where..

    you're making more than one little stupid mistake...

    Code:
    char buf[BUFSIZ + 1];
    int count=0;
    float input,sum;
    min=32356; /*missing type specifiers here*/
    max=-32356;
    Judging by the printfs later, they're supposed to be ints.

    next, you were told about gets already, by Salem no less. Don't use it. Ever. Full Stop.

    atof returns double, not float (deceptively). In fact, there's hardly any reason to use float variables, doubles are better.

    Code:
    	if (min > input)
    		min=input;
    	if (max < input)
    		max=input;
    		
           sum +=input;
    	
    	//diagnostics
    	printf("input%i\n",input);
    Now in these lines, input is float, min and max are int, so you are casting - not good. Also, sum is not initialised here, and you should use %f for printing the input variable.

    Code:
    while (strlen(buf) > 0);
    Need to include string.h to use strlen.

    Lastly, to answer your question, you press enter to break your loop - the loop runs all the way through when you press enter (doesn't quit immediately). The result is that atof is called on an invalid string, and is returning 0 on error, which is less than any of your test values (you never tried a negative value) - so it overwrites your value.

    To fix it - I'd redesign your program quite a bit - I'd use fgets to read input, then use something like strtol (or strtod if you insist of floating point), to break the loop I'd try something like typing q (in which case you'd use an if statement to check the value entered with strcmp, and if the value entered was q, break).
    No No's:
    fflush (stdin); gets (); void main ();


    Goodies:
    Example of fgets (); The FAQ, C/C++ Reference


    My Gear:
    OS - Windows XP
    IDE - MS Visual C++ 2008 Express Edition


    ASCII stupid question, get a stupid ANSI

  10. #10
    Registered User
    Join Date
    Oct 2004
    Posts
    151
    1. #include <limits.h> and initialize "min" and "max" to INT_MIN and INT_MAX respectively, becuase you'll break on moderately pathological inputs.
    2. GET THE HELL RID OF gets() ALREADY!
    3. That code won't even compile. "min" and "max" aren't declared and you use strlen without <string.h>

    Edit: Whoops, slow internet connection.
    System: Debian Sid and FreeBSD 7.0. Both with GCC 4.3.

    Useful resources:
    comp.lang.c FAQ | C++ FQA Lite

  11. #11
    The Richness... Richie T's Avatar
    Join Date
    Jan 2006
    Location
    Ireland
    Posts
    469
    >>1. #include <limits.h> and initialize "min" and "max" to INT_MIN and INT_MAX respectively,

    other way around?
    No No's:
    fflush (stdin); gets (); void main ();


    Goodies:
    Example of fgets (); The FAQ, C/C++ Reference


    My Gear:
    OS - Windows XP
    IDE - MS Visual C++ 2008 Express Edition


    ASCII stupid question, get a stupid ANSI

  12. #12
    Registered User
    Join Date
    Oct 2004
    Posts
    151
    Quote Originally Posted by Richie T
    >>1. #include <limits.h> and initialize "min" and "max" to INT_MIN and INT_MAX respectively,

    other way around?
    Um, yes. =D
    System: Debian Sid and FreeBSD 7.0. Both with GCC 4.3.

    Useful resources:
    comp.lang.c FAQ | C++ FQA Lite

  13. #13
    Registered User
    Join Date
    Sep 2006
    Posts
    4

    Smile

    Thanks guys. I'll try your suggestions and see what happens.

  14. #14
    Registered User
    Join Date
    Sep 2006
    Posts
    4
    Quote Originally Posted by Richie T
    >>

    Lastly, to answer your question, you press enter to break your loop - the loop runs all the way through when you press enter (doesn't quit immediately). The result is that atof is called on an invalid string, and is returning 0 on error, which is less than any of your test values (you never tried a negative value) - so it overwrites your value.

    To fix it - I'd redesign your program quite a bit - I'd use fgets to read input, then use something like strtol (or strtod if you insist of floating point), to break the loop I'd try something like typing q (in which case you'd use an if statement to check the value entered with strcmp, and if the value entered was q, break).


    Well again thank you guys for the answers and all these suggestions, I did manage to get the code to work (just didn't think throughly enough).
    Last edited by rQQt; 09-21-2006 at 01:59 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 02-08-2009, 09:26 PM
  2. Random Number Range Problem.
    By xamlit in forum C Programming
    Replies: 11
    Last Post: 01-26-2006, 12:55 PM
  3. HELP! Min Max values using array.
    By steverushby in forum C++ Programming
    Replies: 6
    Last Post: 11-28-2005, 10:13 AM
  4. Passing a 2d array by Reference
    By loko in forum C Programming
    Replies: 8
    Last Post: 07-23-2005, 06:19 AM
  5. finding max values in an array
    By Unregistered in forum C Programming
    Replies: 3
    Last Post: 01-29-2002, 02:47 PM