3

I am super new to programming and I am having a problem with one of the questions where i am supposed to write a C program to let the user enter some numbers and sort the entered elements and find the median of it. And it should stop getting inputs once the user presses enter. this is my code and idk where it went wrong(btw sorry for asking such a simple question)

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n;
    int i = 0;
    int j,k,m,num;
    int arr[20];
    
    while(i<20 )
    {
        printf("Enter a number: ");
        scanf("%d",&num);
        if(num == '\n') break;
        arr[i] = num;
        i++;
    }
    
    n = sizeof(arr)/sizeof(arr[0]);

    for(i=0;i<n;i++)
    {
        for(j=i+1;j<n;j++)
        {
            if(arr[i] < arr[j])
            {
                k = arr[i];
                arr[i] = arr[j];
                arr[j] = k;
            }
        }
    }
    
    if(n%2 != 0)
    {
        printf("The median is %d", arr[n/2]  ) ;
    }
    else printf("The median is %.2f", arr[(n-1)/2] + arr[n/2]/2.0);

    return 0;
            
} 
Lolly
  • 33
  • 5
  • 3
    With `scanf("%d",&num);` you are reading a string like `123` or `456` as a an integer. But then you try to use it like a character `if(num == '\n') break;`. The condition `num == '\n'` will only be true if you enter the number 10 – Ackdari Jul 27 '20 at 13:37
  • Does this answer your question? [how do we test the return values from the scanf() function?](https://stackoverflow.com/questions/10084224/how-do-we-test-the-return-values-from-the-scanf-function) – Hulk Jul 27 '20 at 13:38
  • By inputting to a string with `fgets()`. The empty (except newline) string terminates the program otherwise process it with `sscanf()`. – Weather Vane Jul 27 '20 at 13:38
  • 2
    "else printf("The mediun is %.2f", arr[(n-1)/2] + arr[n/2]/2.0);" at this line, you might want to use parentheses around summation – t.m. Jul 27 '20 at 13:39

2 Answers2

3

If you want to stop on empty line, you cannot use scanf. The reason is that scanf("%d", ...) skips all whitespace characters from user input while waiting for the use to enter a number. Here "whitespace" includes the new-line character '\n'. So the user cannot make scanf return by pressing Enter - only an end-of-file (Ctrl+D on linux) or bogus input (non-number) will make scanf return.

So you have to replace scanf by the combination fgets+sscanf. Consider the following code:

while (i < 20)
{
    int num;
    char str[15];

    printf("Enter a number: ");
    if (!fgets(str, sizeof str, stdin))
        break;
    if (sscanf(str, "%d", &num) != 1)
        break;
    arr[i] = num;
    i++;
}

It uses fgets to input a line of input, and sscanf to parse that line. If there is nothing in the line, sscanf will fail (it returns 1 for success; any other value for failure).

Notes:

  • If input is too long, it will be split into two lines, which will be surprising for the user
  • If the user inputs more than one number on the line, extra numbers will be silently ignored
  • The condition of fgets's return value terminates user input also on end-of-file; this is good if you supply input to your program by redirecting it from a file
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
anatolyg
  • 26,506
  • 9
  • 60
  • 134
1

Input could be processed character by character until either twenty integers are stored or a newline is found.
As digits are read, accumulate them into a value, checking for overflow.
Upon reading whitespace or another character, store the values in the array.

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

int main ( void) {
    int ch = 0;
    int value = 0;
    int sign = 1;
    int digits = 0;
    int arr[20] = { 0};
    int n = 0;
    int i = 0;
    int j = 0;
    int k = 0;

    while ( n < 20) {
        while ( EOF != ( ch = fgetc ( stdin))) {//read a character
            if ( isdigit ( ( unsigned char)ch)) {
                ch -= '0';//character to int as '1' to 1
                digits = 1;
                if ( 1 == sign) {
                    if ( value < ( INT_MAX / 10) - ch) {
                        value *= 10;
                        value += ch;
                    }
                    else {
                        printf ( "overflow! reset to + and zero\n");
                        value = 0;
                        sign = 1;
                        digits = 0;
                    }
                }
                if ( -1 == sign) {
                    if ( value > ( INT_MIN / 10) + ch) {
                        value *= 10;
                        value -= ch;
                    }
                    else {
                        printf ( "overflow! reset to + and zero\n");
                        value = 0;
                        sign = 1;
                        digits = 0;
                    }
                }
            }
            else if ( '-' == ch || '+' == ch) {
                if ( digits) {
                    printf ( "invalid sign! reset to + and zero\n");
                    value = 0;
                    sign = 1;
                    digits = 0;
                }
                else {
                    sign = ( '-' == ch) ? -1 : 1;
                }
            }
            else if ( digits) {
                arr[n] = value;
                value = 0;//reset to zero
                sign = 1;//reset to +
                ++n;
                digits = 0;
            }
            if ( '\n' == ch) {
                break;
            }
        }
        if ( '\n' == ch || EOF == ch) {
            break;
        }
    }

    for ( i = 0; i < n; i++) {
        for ( j = i + 1; j < n; j++) {
            if ( arr[i] < arr[j]) {
                k = arr[i];
                arr[i] = arr[j];
                arr[j] = k;
            }
        }
    }

    for ( i = 0; i < n; i++) {
        printf ( "arr[%d] = %d\n", i, arr[i]);
    }

    if ( n % 2 != 0) {
        printf ( "The median is %d\n", arr[n/2]);
    }
    else {
        printf ( "The median is %.2f\n", ( arr[( n - 1) / 2] + arr[n / 2] ) /2.0);
    }

    return 0;
}

Input and output:

9 1 82   0    3
arr[0] = 82
arr[1] = 9
arr[2] = 3
arr[3] = 1
arr[4] = 0
The median is 3
user3121023
  • 8,181
  • 5
  • 18
  • 16