3
\$\begingroup\$

I made a program that will loop and calculate the average of the input given by the user. There are no problems here. I just want to know if there is a better way to do this, or a way to optimize this code.

How this program works:

First, the program will read a double and a separator in a forever loop until it finds a newline character or a wrong separator. If it finds a space as separator, then it will just continue to read more input. If it finds newline, then it will print the average. If it finds anything else separator, e.g. 'a' or '^', then it will print "error!".

The code:

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

int main(int argc, char *argv[])
{
    double average, num, total;
    char separator;

    for(int i = 1; ; i++) //increment the value as the loop goes
    {
        scanf("%lf%c", &num, &separator);
        total += num;

        if(separator == '\n')
        {
            average = total / i;
            printf("average = %lf\n", average);
            break;
        }
        else if(separator == ' ')
        {
            //do nothing
        }
        else
        {
            while((getchar()) != '\n'); //clear buffer
            printf("error!\n");
            break;
        }
    }

    printf("press ENTER to exit...");
    getchar();
    return 0;
}
\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

Since we don't use any arguments, we could use int main(void) instead.

If we don't successfully read a number, scanf will return 0. But we ignore that and use num anyway, indefinitely (since the input position is never advanced).

The scope of all the variables can be reduced to within the for loop.

while((getchar()) != '\n'); will continue looping indefinitely if the input stream is closed (since EOF != '\n'). Consider ignoring the rest of line with a single call to scanf("%*[^\n]") instead. Alternatively, return EXIT_FAILURE to indicate the problem.

Error messages should go to stderr rather than stdout.

The final printf() and getchar() make it harder to use your program as a filter in a pipe. I would just drop them (and the return 0; that's implied by reaching the end of main()).

\$\endgroup\$
2
\$\begingroup\$

the variable total is never initialized, then it is used as a source value in total += num; which results in undefined behavior.

the posted code does not re-initialize after the '\n' is processed znc your problem description fails to clarify what the proper action should be.

\$\endgroup\$
2
  • \$\begingroup\$ I read a website that default initializing for int is 0, so I just declare the variable without initialized it, as the first initialization would be just 0. Is it right? \$\endgroup\$
    – manungsa
    Commented May 24, 2022 at 8:43
  • \$\begingroup\$ btw, I don't understand about the undefined behavior, as my code seem to work without any problem(at least when I test it) \$\endgroup\$
    – manungsa
    Commented May 24, 2022 at 8:53

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.