0

In my code, the program will not allowed the negative number entered, the program will stop reading, then calculate the maximum value, minimum value and average value. That is my code

#include <stdio.h>

int main(void) {
  int age[10] = {0};              // initalized an array
  printf("Please enter ages: \n");  // allow user to enter numbers


  for (int i = 0 ;i < 10; i++) {
    scanf("%d",&age[i]);
    if (age[i] < 0) { // if it is negative number, it is should stop reading
      break;
    }
    else if (age[i] >= 0) {
      continue;
    }
  }
  int maximum = age[0];
  int minimum = age[0];
  float average = 0.0;
  int length = sizeof(age) / sizeof(age[0]);
  for (int j = 0; j < length; j++) {
    if (maximum < age[j]) {
      maximum = age[j];
    } 
    else if (minimum > age[j]) {
      minimum = age[j];
    }
    average += age[j];
  }

  average = average / length;
  printf("%d\n", maximum);
  printf("%d\n", minimum);
  printf("%.1f\n", average);

  return 0;
}

Please enter ages: 5 -1 expected result: max:5;min:5,average:5;

actual result: max:5;min:-1,average: 0.4;

That was a question that I met, the code should not accept any negative value.

Thank you all. but if I add age[i] = 0; then break; The average value will equal to 0.5.

14
  • Instead of break which just breaks out of the loop, print an error message and stop the program. For example with return 0;. Commented May 12, 2022 at 9:00
  • Actually I'm not sure what you are asking here. "the program will not allowed the negative number entered, the program will stop reading" ... "my program will accept a negative number then stop reading". Please clarify which one that is the desired behavior (what the program should do) and which one is the incorrect behavior you are getting instead. Commented May 12, 2022 at 9:02
  • just setting age[i] = 0; before the break; in the first if would solve the problem I think! Commented May 12, 2022 at 9:03
  • @MohamadGhaithAlzin Irrelevant – the array is zero-initialised anyway, note the = { 0 } after the declaration. Commented May 12, 2022 at 9:05
  • @Mohamad Ghaith Alzin But the average value will equal to 0.5 Commented May 12, 2022 at 9:05

5 Answers 5

3
  • You don't need an array.
  • You don't need both a loop variable and a length.
  • It's more appropriate to use ? : for updating minimum/maximum.
  • You don't need two loops
  • You need to check the int return value of scanf(), which indicates the number of items successfully scanned, so it should be 1. I'll leave that for you/OP to add (hint: replace for-loop by while-loop to avoid having to add a separate length variable again).
    int main(void)
    {
        printf("Please enter ages: \n");

        int minimum = INT_MAX;
        int maximum = 0;
        int sum = 0;
        int count = 0;

        for (count = 0; count < 10; count++)
        {
            int age;
            scanf("%d", &age);

            if (age < 0)
            { 
                break;
            }

            sum += age;

            minimum = (age < minimum) ? age : minimum;
            maximum = (age > maximum) ? age : maximum;
        }

        if (count > 0)
        {
            printf("Min: %d\n", minimum);
            printf("Max: %d\n", maximum);
            printf("Avg: %.1f\n", (float)sum / count);
        }
        else
        {
            printf("You didn't enter (valid) age(s).\n");
        }

        return 0;
    }
Sign up to request clarification or add additional context in comments.

10 Comments

Great answer – but you missed the point when no valid number has been entered thus count yet being 0... I'd add, too, checking the result of scanf and add an explanation for why that's necessary.
Still missing: if(count == 0) /*!!!*/ { /* error message */ } else { /* printing the output */ } – with comment for the rest I'm fine.
Well, would really wonder who wouldn't have understood the original if – sometimes people rather ask for what the ternary means (well, one should know the language, sure...). Ternary is mainly nice for its brevity (like std::min or std::max in C++) – and luckily we have optimising compilers that should get rid of the self-assignment...
Aside: Consider (double) instead of float in printf("Avg: %.1f\n", (float)sum / count);. Quotient gets promoted to double anyways as part of a ... argument.
This is an excellent example of an on-line algorithm, which doesn't need to store history. One could go to 10 of 1000000 without increasing it's footprint. (The sum will probably overflow eventually; see algorithms for calculating varience.)
|
1

Your approach is overly complicated and wrong.

You want this:

  ...
  int length = 0;    // declare length here and initialize to 0

  for (int i = 0; i < sizeof(age) / sizeof(age[0]); i++) {
    scanf("%d", &age[i]);

    if (age[i] < 0)  // if it is negative number, it is should stop reading
      break;

    length++;        // one more valid number
  }
  
  // now length contains the number of numbers entered
  // the rest of your code seems correct

You also might need to handle the special case where no numbers are entered, e.g: the only thing entered is -1. It doesn'make sense to calculate the average or the largest/smallest number when there are no numbers.

4 Comments

Also, length can be used a loop variable like I did.
Please add a hint that length == 0 needs to be handled explicitly – and I'd did so, too, for checking the result of scanf...
@Aconcagua checking if scanf fails is pretty pointless IMO because using scanf for interactive input is pointless anyway, scanf is just good enough for student's toy programs.
In a way, yes, but she/he'll won't do it on sscanf after reading entire lines either (or by input from files)...
0

A possible solution could be:

(corrections are written in the commented code)

#include <stdio.h>

int main(void){
  int arraySize = 10;
  int age[arraySize]; //initialize not required
  
  //the number of existing values inside the array (effective length)
  int length = 0;

  printf("Please enter ages: \n");  // allow user to enter numbers

  for(int i=0; i<arraySize; i++){
    scanf("%d",&age[i]);
    
    // if it is negative number, it is should stop reading
    if(age[i]<0){ break; }
    
    //the else-if is not required
    //but, if the compiler goes here,
    //it means that the value is acceptable, so
    length++;
  }

  int maximum = age[0];
  int minimum = age[0];
  float average = 0.0;
   
  for(int j=0; j<length; j++){
    if(maximum<age[j]){ maximum = age[j]; } 
    else if(minimum>age[j]) { minimum = age[j]; }
    average += age[j];
  }

  average = average / length;
  printf("%d\n", maximum);
  printf("%d\n", minimum);
  printf("%.1f\n", average);

  return 0;
}

6 Comments

@Aconcagua The code is already edited. Now the length is calculated in the first loop.
I'd yet initialise average with age[0] as well, then you can start iterating at index 1, so skipping the needless checks for maximum/minimum at index 0.
You need to additionally handle the case for length being 0 – at best right after the first loop by returning, ideally printing some appropriate error message right before.
@Aconcagua I think that the initialisation of the average var with age[0] wouldn't be a great idea, but it's just my opinion. On the other hand, the code has to be updated, so it can handle the case length = 0. Thx for those advices. :)
You left updating minimum and maximum with age[0] anyway, so what's the difference for the average? All of aren't valid anyway if no valid input is given at all – and if you catch that in advance (as promised), then age[0] is valid, so you can use it and skip needlessly checking minimum and maximum for very first index.
|
0

OP's primary problem is the 2nd loop iterates 10 times and not i times (the number of times a non-negative was entered.


For fun, let us try a non-floating point solution as it really is an integer problem.

An array to store values is not needed.

#include <limits.h>
#include <stdio.h>

int main(void) {
  // Keep track of 4 things
  int min = INT_MAX; // Set min to the max int value.
  int max = INT_MIN;
  long long sum = 0; // Use wide type to cope with sum of extreme ages.
  int count = 0;

  #define INPUT_N 10

  printf("Please enter ages: \n");
  
  for (count = 0; count < INPUT_N; count++) {
    int age;
    if (scanf("%d", &age) != 1) {
      fprintf(stderr, "Missing numeric input.");
      return EXIT_FAILURE;
    }
    if (age < 0) {
      break;
    }

    if (age < min) min = age;
    if (age > max) max = age;
    sum += age;
  }

  if (count == 0) {
    fprintf(stderr, "No input.");
    return EXIT_FAILURE;
  }

  printf("Maximum: %d\n", max);
  printf("Minimum: %d\n", min);

  // Could use FP and 
  // printf("Average: %.1f\n", 1.0 *sum / count);
  // But for fun, how about a non-FP approach?
 
  #define SCALE 10
  #define SCALE_LOG 1
  sum *= SCALE; // Scale by 10 since we want 1 decimal place.
  // Perform a rounded divide by `count`
  long long average_scaled = (sum + count/2) / count;
  // Print the whole and fraction parts
  printf("Average: %lld.%.*lld\n", 
      average_scaled / SCALE, SCALE_LOG, average_scaled % SCALE);

  return 0;
}

Comments

-1

First of all, you must record how many positive numbers you enter. Then the value of length will be correct.

Second, for the second for loop, j must be smaller than the number of positive ages. Therefore, you won't add negative age[j] to average.

You can simply modify the second for loop.

#include <stdio.h>

int main(void) {
  int age[10] = {0};              // initalized an array
  printf("Please enter ages: \n");  // allow user to enter numbers


  int length = 0;

  for (int i = 0 ;i < 10; i++) {
    scanf("%d",&age[i]);
    if (age[i] < 0) { // if it is negative number, it is should stop reading
      break;
    }
    else if (age[i] >= 0) {
      length++;
      continue;
    }
  }
  int maximum = age[0];
  int minimum = age[0];
  float average = 0.0;

for (int j = 0; j < length; j++) {
    if (maximum < age[j]) {
      maximum = age[j];
    } 
    else if (minimum > age[j]) {
      minimum = age[j];
    }

    if ( age[j] > 0.0 )
    {
      average += age[j];
    }
  }

  average = average / length;
  printf("%d\n", maximum);
  printf("%d\n", minimum);
  printf("%.1f\n", average);

  return 0;
}

9 Comments

While, the average value will equal to 0.5.
The expected result of average value should be 5 here
And the minimum value also 5
if ( age[j] > 0.0 ) – this test is obsolete – adding 0 to a float won't change it and the if likely is more expensive than the addition. It would be definitively if you built the sum as pure ints and only converted to float afterwards. Code suffers from the same bad style than the original one in the questions, see my comments there.
Handling the special case of length being 0 is lacking.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.