Diana Wright
Diana Wright

Reputation: 31

Creating GPA calculator in C code

I just wrote this code and I cannot get it to work - not to mention output the desired results. I am supposed to create a program that will calculate the GPA of an unknown amount of students (which I have narrowed down to a max of 25) with an unknown amount of classes respectively (also narrowed those down to a max of 10 to make my life easier).

Can anyone see what mistakes I have made and possibly push me in the right direction? I appreciate anyone's time and advice :)

My Code:

// C Program - GPA calculator for x amount of students with x amount of classes
// Program developer: Diana Wright - Novembet 22nd, 2014
#include <stdio.h>

int main(void) {

    // Declare variables
    int grade[5], g, class_num[9], c;
    char name[24], n;
    float GPA=0.0, grade_point=0.0, result=0.0;

    // Input student names implying amount of students
    for(n=0; n<25; n++) {
        scanf(" %s", &name[n]);
        printf("Please enter student names: %s.", name[n]);

        // Input number of classes
        for(c=0; c<10; c++) {
            scanf(" %d", &class_num[c]);
            printf("Please enter amount of classes (max.10): %d", class_num[c]);

            // Input grades
            for(g=0; g<=class_num; g++) {
                scanf(" %d", &grade[g]);    
                printf("Please enter students' grades: %d.", grade[g]);
            }

            // Conversion of grades
            if (grade == "A"){
                grade_point = 4.0;
            }
            if (grade == "B"){
                grade_point = 3.0;
            }
            if (grade == "C")
            {
                grade_point =2.0;
            }
            if (grade == "D"){
                grade_point = 1.0;
            }
            if (grade == "F"){
                grade_point = 0.0;
            }

            // Formula to calculate GPA
            result += grade_point[g];
            GPA = result/class_num[c];
        }
    }

    // Print user input and results in a table
    printf(“\n Student name \t Grades \t GPA”);
    for(n=0; n<25; n++) {
        printf(“ %s \t %d \t %f”, name[n], grade[g], GPA);
    }
    return 0;
}

My initial input:

Diana 3 A A A Edward 4 B C B A Stuart 4 A F C D Bert 2 F F

Upvotes: 3

Views: 28990

Answers (3)

user3629249
user3629249

Reputation: 16540

// the following implements the needed data set,
// corrects several coding errors
// has (not yet run) compiling code

EDIT: following code obsolete, see new code further down

#include <stdio.h>
#include <string.h>

struct studentGrade
{
    char name[24];
    char grades[10];
    int  class_num;
    float GPA;
};


int main(void)
{

    // Declare variables
    struct studentGrade studentGrades[25] = {{"",{'F','F','F','F','F','F','F','F','F','F'},0,0.0F}};


    int  c; // index into student grades[]

    int n; // student number/loop counter


    float grade_point=0.0f, result=0.0f;

    // Input student names implying amount of students
    for(n=0; n< (sizeof( studentGrades)/sizeof(struct studentGrade)); n++)
    {
        result = 0.0f; // initialize for each student

        printf( "please enter student name:\n     ");
        scanf(" %s", (char*)(studentGrades[n].name) );
        printf("Student Name is: %s.", studentGrades[n].name);

        printf("please enter student class count:\n");
        scanf(" %d", &studentGrades[n].class_num);
        printf("Student Number of classes: %d", studentGrades[n].class_num);

        // Input class grades
        for(c=0; c< 10; c++)
        {
            printf("please enter grade for class: %d", c);
            scanf(" %c", &(studentGrades[n].grades[c]));
            printf("student grade for class: %d is %c\n", c, studentGrades[n].grades[c]);


            // following makes wild assumption that grade entered
            // is 'A'...'F'
            // Conversion of grades
            grade_point = 0.0f; // init for each class
            switch( studentGrades[n].grades[c] )
            {
                case 'A':
                    grade_point = 4.0f;
                    break;

                case 'B':
                    grade_point = 3.0f;
                    break;

                case 'C':
                    grade_point = 2.0f;
                    break;

                case 'D':
                    grade_point = 1.0f;
                    break;

                case 'F':
                    grade_point = 0.0f;
                    break;

                default:
                    printf( "invalid grade entered\n");
                    c--; // so will properly handle loop control, etc
                    break;
            }  // end switch
            result += grade_point;


            // Formula to calculate GPA
            result += grade_point;
        } // end for each grade

        studentGrades[n].GPA = result/(float)c;
    } // end for each student

    // Print user input and results in a table
    printf("\n Student name \tGPS\n\t\tgrades\n");

    for(n=0; n< (sizeof(studentGrades) / sizeof( struct studentGrade)); n++)
    {
        if( 0 != strlen(studentGrades[n].name) )
        {
            printf( " %s \tGPS: %.2f\n",
                studentGrades[n].name,
                studentGrades[n].GPA);
            for( c=0; c< studentGrades[n].class_num; c++)
            {
                printf("\tclass: %d\t%c:\n", c, studentGrades[n].grades[c] );
            }
        }
    }
    return 0;
}

EDIT: New code:

  1. cleanly compiles
  2. properly checks for errors
  3. uses #define statements to eliminate 'magic' numbers
  4. cleans up the logic error of always trying to input 10 grades
  5. allows both upper case and lower case grade entry
  6. uses meaningful variable names
  7. incorporates appropriate horizontal spacing for readability

and now the new code:

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

#define MAX_STUDENTS 25
#define MAX_NAME_LEN 23
#define MAX_GRADES   10


#define STR_VALUE(x) STR(x)
#define STR(x) #x



struct studentGrade
{
    char name[ MAX_NAME_LEN+1 ];
    char grades[ MAX_GRADES ];
    int  class_num;
    float GPA;
};


int main(void)
{
    // Declare variables
    struct studentGrade studentGrades[ MAX_STUDENTS ] =
    {
        {"",
            {'F','F','F','F','F','F','F','F','F','F'}
            ,0,
            0.0F
        }
    };



    float result      = 0.0f;

    // Input student names implying amount of students
    for( size_t whichStudent=0;
        whichStudent < (sizeof( studentGrades)/sizeof(struct studentGrade));
        whichStudent++)
    {
        result = 0.0f; // initialize for each student

        printf( "please enter student name:\n     ");

        if( scanf(" %" STR_VALUE(MAX_NAME_LEN) "s",
                studentGrades[ whichStudent ].name ) != 1 )
        {
            fprintf( stderr, "scanf for student name failed");
            exit( EXIT_FAILURE );
        }

        // implied else, scanf for student name successful
        printf("Student Name is: %s.",
                studentGrades[ whichStudent ].name);

        printf("please enter student class count:\n");
        if( scanf(" %d", &studentGrades[ whichStudent ].class_num) != 1 )
        {
            fprintf( stderr, "scanf for student class count failed\n" );
            exit( EXIT_FAILURE );
        }

        // implied else, scanf for student class count successful

        printf("Student Number of classes: %d",
            studentGrades[ whichStudent ].class_num);

        // Input class grades
        for( int whichClass=0;
            whichClass < studentGrades[ whichStudent ].class_num;
            whichClass++)
        {
            printf( "please enter grade for class: %d", whichClass );
            if( scanf( " %c",
                        &(studentGrades[ whichStudent ].
                            grades[ whichClass ]) ) != 1)
            {
                fprintf( stderr,
                        "scanf for class grade %d failed\n",
                        whichClass );
                exit( EXIT_FAILURE );
            }

            // implied else, scanf for class grade successful

            printf( "student grade for class: %d is %d\n",
                whichClass,
                studentGrades[ whichStudent ].grades[ whichClass ] );


            // following makes wild assumption that grade entered
            // is 'A'...'F'
            // Conversion of grades
            float grade_point = 0.0f; // init for each class
            switch( studentGrades[ whichStudent ].grades[ whichClass ] )
            {
                case 'A':
                case 'a':
                    grade_point = 4.0f;
                    break;

                case 'B':
                case 'b':
                    grade_point = 3.0f;
                    break;

                case 'C':
                case 'c':
                    grade_point = 2.0f;
                    break;

                case 'D':
                case 'd':
                    grade_point = 1.0f;
                    break;

                case 'F':
                case 'f':
                    grade_point = 0.0f;
                    break;

                default:
                    printf( "invalid grade entered\n");
                    whichClass--; // so will properly handle loop control, etc
                    break;
            }  // end switch
            result += grade_point;


            // Formula to calculate GPA
            result += grade_point;
        } // end for each grade

        studentGrades[ whichStudent ].GPA =
            result/(float)studentGrades[ whichStudent ].class_num;
    } // end for each student

    // Print user input and results in a table
    printf( "\n Student name \tGPS\n\t\tgrades\n" );

    for( size_t whichStudent=0;
         whichStudent < (sizeof(studentGrades) / sizeof( struct studentGrade));
         whichStudent++ )
    {
        if( 0 != strlen( studentGrades[ whichStudent ].name ) )
        {
            printf( " %s \tGPS: %.2f\n",
                studentGrades[ whichStudent ].name,
                studentGrades[ whichStudent ].GPA );

            for( int whichClass=0;
                  whichClass < studentGrades[ whichStudent ].class_num;
                  whichClass++)
            {
                printf( "\tclass: %d\t%c:\n",
                    whichClass,
                    studentGrades[ whichStudent ].grades[ whichClass ] );
            }
        }
    }
    return 0;
}

Upvotes: 2

KillaBytes
KillaBytes

Reputation: 447

So not to get on your case about anything whether this is or is not homework and to give credit to what laughingpine and Gopi have said already said...

There are some glaring errors in your code that will prevent you from compiling and running to have any effect. To start lets look at your declaration of variables:

// Declare variables
// You don't initialize any of your char or int non array and array variables. 
int grade[5], g, class_num[9], c;
char name[24], n;
float GPA=0.0, grade_point=0.0, result=0.0; // You initialize your floating point variables.

When you initialize the compiler will designate an area of memory that these variables will reside in. If you don't then the compiler starts to make 'assumptions' on the variables you are using and will assign random memory locations to your variables. Next:

for (c = 0; c<10; c++) {
        scanf(" %d", &class_num[c]); // You ask the user to enter one digit at a time for the class number
        printf("Please enter amount of classes (max.10): %d", class_num[c]); 

        // Input grades
        for (g = 0; g <= class_num; g++) // You try and make a comparison to a single variable int to an entire array which is not allowed.
        {
            scanf(" %d", &grade[g]);
            printf("Please enter students' grades: %d.", grade[g]);
        }

You cannot compare a single variable to an entire array, this line for (g = 0; g <= class_num; g++)will not compile. Another:

if (grade == "A"){
        grade_point = 4.0;
        }

You try to make a comparison from grade which is an int data type in your case to a string/character literal "A"which is not allowed...

result += grade_point[g]

Grade_point becomes an array here, when it was not defined this way before...

This looks like you rushed through the design process of your program. I recommend you sit down with a piece of paper and a pencil/pen and write out what it is you are trying to accomplish at each stage of asking the user for input. This will help in defining what variable data types you should be using in order to accomplish your tasks.

Upvotes: 1

laughingpine
laughingpine

Reputation: 1049

Little rusty on this stuff, but I think there are a few strange things happening here that may not have been intended.

for(g=0; g<=class_num; g++) 

Think we are looking for the inputted value that is stored at offset c, not the array.

for(c=0; c<10; c++)

I am not quite sure of the value of this loop. We should only have to get the number of classes once per student.

if (grade == "A")

Again, this didn't grab the right offset in the array. Do comparisons to char's need single quotes?

You are also going to have your print statements printing out a bunch... for example you might want to move this line outside the loop:

printf("Please enter students' grades: %d.", grade[g]);

Upvotes: 1

Related Questions