0

whats wrong in my code? it doesn't give the values properly and when i insert q it doesn't execute properly....

#include<stdio.h>
void main()
{
    double a=0, x, ctot;
    double y, stot;
    char b, c='q';
    double score=x*y;
    while(a<200){
     printf("Enter no of Credits of the subject = ");
     scanf("%lf\n",&x);
     printf("Enter the score for the subject = ");
     scanf("%lf\n",&y);
     scanf("%c\n",&b);
    if(b=='q'){
            break;
    }else{

            ctot+=x;
            stot+=score;
            a++;
    }
}
    printf("GPA of the student = %f\n", stot/ctot);
}
Minura
  • 9
  • 2
  • 4
    `ctot` and `stot` are not initialized. – mch May 07 '18 at 06:39
  • 2
    `gcc -Wall file.c` gives 6 warnings. If you compile with warnings on, you'll often find problems before running your program. – Paul Hankin May 07 '18 at 06:42
  • 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)](http://port70.net/~nsz/c/c11/n1570.html#5.1.2.2.1p1). See also: [See What should main() return in C and C++?](http://stackoverflow.com/questions/204476/) – David C. Rankin May 07 '18 at 06:48
  • Also, you must check the **return** of `scanf` *every time* and you had better change `"%c"` to consume all leading whitespace, e.g. `" %c"` or your will find that input is skipped and `b=10` every time. (can you figure out why?) – David C. Rankin May 07 '18 at 06:51
  • In addition to `ctot` and `stot` being uninitialized, what is the value of `score` after `double score=x*y;` (and hint: you invoke *Undefined Behavior* when you attempt to read from an uninitialized value) – David C. Rankin May 07 '18 at 06:54
  • your `double score=x*y;` will not work . I should be after reading `x` and `y` – anoopknr May 07 '18 at 07:01

3 Answers3

1

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.

David C. Rankin
  • 69,681
  • 6
  • 44
  • 72
0

Initializing ctot and stot and re-positioning score=x*y your code will work . Try this edited code this works fine :-

#include <stdio.h>
void main()
{
    double a = 0, x, ctot;
    double y, stot;
    char b, c = 'q';
    double score;

    ctot = 0;   // initialize ctot and stot    #ERROR1
    stot = 0;

    while (a < 200)
    {
        printf("\n Enter no of Credits of the subject = ");
        scanf("%lf", &x);
        printf("\n Enter the score for the subject = ");
        scanf("%lf", &y);
        getchar(); // to manage the addtional \n from scanf()

        score = x * y; //     computing score         #ERROR2

        scanf("%c", &b);

        if (b == 'q')
        {
            break;
        }
        else
        {

            ctot += x;
            stot += score;
            a++;
        }
    }
    printf("\n GPA of the student = %f", stot / ctot);
}

based on comments of @mch and @David C. Rankin

anoopknr
  • 2,505
  • 2
  • 14
  • 25
0

should modify the slot+=score to slot+=x*y

#include<stdio.h>
void main()
{
    double a=0, x, ctot;
    double y, stot;
    char b, c='q';
    double score=x*y;
    while(a<200){
     printf("Enter no of Credits of the subject = ");
     scanf("%lf\n",&x);
     printf("Enter the score for the subject = ");
     scanf("%lf\n",&y);
     scanf("%c\n",&b);
    if(b=='q'){
            break;
    }else{

            ctot+=x;
            stot+=x*y;
            a++;
    }
}
    printf("GPA of the student = %f\n", stot/ctot);
}
  • Some explanations and better code formatting would be helpful. Click on edit below your answer to modify/improve it. – jps May 07 '18 at 07:28