【问题标题】:Creating GPA calculator in C code用 C 代码创建 GPA 计算器
【发布时间】:2014-11-23 05:12:37
【问题描述】:

我刚刚编写了这段代码,但我无法让它工作——更不用说输出所需的结果了。我应该创建一个程序,分别计算未知数量的学生(我已将其缩小到最多 25 个)和未知数量的课程(也将这些学生的 GPA 缩小到最多 10 个,以使我的生活更轻松)。

谁能看到我犯了哪些错误并可能将我推向正确的方向?我感谢任何人的时间和建议:)

我的代码:

// 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;
}

我的初始输入:

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

【问题讨论】:

  • grade == "A" 这是错误的! Grade 是 int 类型,您正在为其分配一个字符串
  • 这一行:scanf("%s", &name[n]);处于一个循环中,该循环逐渐将名称放置在更远的右字符位置。最好总是将名称放在已知位置,例如通过定义 name[25][50] = {{'\0'}};然后scanf(" %s", &name[n][0]);代码中还有其他地方有类似问题。

标签: c


【解决方案1】:
// the following implements the needed data set,
// corrects several coding errors
// has (not yet run) compiling code

编辑:以下代码已过时,请进一步查看新代码

#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;
}

编辑:新代码:

  1. 干净编译
  2. 正确检查错误
  3. 使用#define 语句消除“神奇”数字
  4. 清理总是尝试输入10个等级的逻辑错误
  5. 允许大写和小写成绩输入
  6. 使用有意义的变量名
  7. 包含适当的水平间距以提高可读性

现在是新代码:

#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;
}

【讨论】:

  • 嗯...谢谢你。但不知何故,它永远不会计算 GPA 部分,因为循环一直在继续。我一直试图弄乱代码一段时间,但我仍然无法让它正常工作。当我只输入三个学生,每个学生只有四个成绩时,代码会将下一个学生姓名的每个字母变成一个成绩,并说这是一个无效的成绩(当然是,因为它是一个学生的名字)......不要不知道出了什么问题。
【解决方案2】:

这东西有点生疏,但我认为这里发生了一些可能不是故意的奇怪事情。

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

假设我们正在寻找存储在偏移量 c 处的输入值,而不是数组。

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

我不太确定这个循环的价值。我们应该只需要为每个学生获取一次班级数量。

if (grade == "A")

同样,这并没有在数组中获取正确的偏移量。与 char 的比较是否需要单引号?

您还将打印出一堆打印语句...例如,您可能希望将此行移到循环之外:

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

【讨论】:

    【解决方案3】:

    因此,无论这是否是家庭作业,都不要对你的案子提出任何质疑,并赞扬笑松和 Gopi 已经说过的话......

    您的代码中有一些明显的错误会阻止您编译和运行以产生任何影响。首先让我们看看你的变量声明:

    // 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.
    

    当您初始化时,编译器将指定这些变量将驻留的内存区域。如果您不这样做,编译器就会开始对您正在使用的变量进行“假设”,并将随机内存位置分配给您的变量.下一个:

    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]);
            }
    

    您不能将单个变量与整个数组进行比较,这一行 for (g = 0; g &lt;= class_num; g++) 将无法编译。另一个:

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

    您尝试将等级(在您的情况下是 int 数据类型)与字符串/字符文字 "A" 进行比较,这是不允许的...

    result += grade_point[g]
    

    Grade_point 在这里变成了一个数组,之前没有这样定义过...

    这看起来像是您匆忙完成了程序的设计过程。我建议你坐下来,拿着一张纸和一支铅笔/钢笔,写下你在询问用户输入的每个阶段要完成的工作。这将有助于定义您应该使用哪些变量数据类型来完成您的任务。

    【讨论】:

    • 谢谢。我实际上花了四个多小时在这上面。直到凌晨2点左右才上床睡觉。所以你指出了我做错的一切。但是规则是什么,因为我做的一些事情是不允许的?
    • @DianaWright 我很乐意帮助您编写代码并指导您朝着正确的方向前进,但不幸的是,我无法在这个小小的评论部分中做到这一点:(。看看其中的一些网站,看看是否有什么能引导你找到答案,我建议你去拜访了解 C 编程并且可以亲自帮助你的人。stackoverflow.com/questions/22676211/…stackoverflow.com/questions/14536139/…
    • 感谢您为我提供链接 :) 我实际上已经从我的大学上过辅导课,但最终对我没有帮助,因为那个女人只是没有听我的问题,而是像对待我一样对待我一个对编码一无所知的人。明天我将与另一位导师面对面。希望这会有所帮助。我真的很想学这个。我其实很喜欢编程,但它会让人很沮丧。
    • 那很好,挫折会导致学习——这是程序员的一部分:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多