An attempt to access a variable with indeterminate value (meaning uninitialized) invokes Undefined Behavior and the valid operation of your code ceases at that point. It can appear to work properly or SegFault
or anything in between.
To avoid uninitialized values, always initialize them -- especially when you are just beginning to program. (it will save you from yourself...), e.g.
int a = 0; /* always initialize all variables - good practice */
double ctot = 0.0,
stot = 0.0,
score = 0.0,
x = 0.0,
y = 0.0;
char c = 0;
The proper declarations for main
are int main (void)
and int main (int argc, char **argv)
(which you will see written with the equivalent char *argv[]
). note: main
is a function of type int
and it returns a value. See: C11 Standard §5.1.2.2.1 Program startup p1 (draft n1570). See also: See What should main() return in C and C++?
While there are some ancient compilers, and some micro-controllers that allow void main()
, it is a non-standard invocation, and any worthwhile compiler will warn. (you are compiling with compiler-warning enabled right?, e.g. -Wall -Wextra
for gcc/clang or /W3
for VS (cl.exe
))
You must check the return of scanf
every time and validate the return is equal to the number of conversions you have requested -- otherwise a matching or input failure has occurred (or the user canceled by generating a manual EOF
). This is the only way you can insure you are processing valid data and not further invoking Undefined Behavior (or throwing yourself into an endless input loop). You must always empty stdin
after each input. Your '\n'
gimick in the format string will not work. A simple way to empty stdin
is to define a helper-function to call after each input to remove any extraneous or additional characters that remain unread, e.g.
/* simple function to empty remaining chars in stdin */
void empty_stdin (void) /* if no parameter - spcecify 'void' explicitly */
{
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
...
printf ("Enter no of Credits of the subject = ");
if (scanf ("%lf", &x) != 1) { /* validate EVERY input */
fprintf (stderr, "error: invalid input for 'x'.\n");
return 1;
}
empty_stdin(); /* empty stdin, your \n gimick doesn't work */
Putting it altogether, you could do something similar to the following:
#include <stdio.h>
/* simple function to empty remaining chars in stdin */
void empty_stdin (void) /* if no parameter - spcecify 'void' explicitly */
{
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
int main (void) {
int a = 0; /* always initialize all variables - good practice */
double ctot = 0.0,
stot = 0.0,
score = 0.0,
x = 0.0,
y = 0.0;
char c = 0;
for (; a < 200; a++) { /* loop however you like */
printf ("Enter no of Credits of the subject = ");
if (scanf ("%lf", &x) != 1) { /* validate EVERY input */
fprintf (stderr, "error: invalid input for 'x'.\n");
return 1;
}
empty_stdin(); /* empty stdin, your \n gimick doesn't work */
printf ("Enter the score for the subject = ");
if (scanf ("%lf", &y) != 1) {
fprintf (stderr, "error: invalid input for 'y'.\n");
return 1;
}
empty_stdin();
score = x * y; /* compute values each iteration */
ctot += x;
stot += score;
/* prompt for additional credits? */
printf ("add additional credits? (y/n): ");
if (scanf (" %c", &c) != 1) {
fprintf (stderr, "error: user canceled input.\n");
return 1;
}
empty_stdin();
if (c == 'n' || c == 'N') /* you can use 'q', but (y/n) is fine */
break;
}
printf ("\nGPA of the student = %f\n", stot/ctot);
return 0;
}
(can you figure out why if (scanf (" %c", &c) != 1)
can only mean that the user canceled input?)
Example Use/Output
note: there are extraneous characters intentionally input below to provide example of how the simple additions to your code handle them safely. (try the input below with your original code and see what happens)
$ ./bin/credits_grades
Enter no of Credits of the subject = 3
Enter the score for the subject = 90
add additional credits? (y/n): y
Enter no of Credits of the subject = 4 (seemed like 40)
Enter the score for the subject = 80 (thank god!)
add additional credits? (y/n): y
Enter no of Credits of the subject = 3
Enter the score for the subject = 85
add additional credits? (y/n): n
GPA of the student = 84.500000
Look things over and let me know if you have further questions.