关于#C语言#结构体多次赋值打印出错的问题,如何解决?

请教各位,求各位指点!本人小垃圾,写个C语言,有个bug解决不了,已经搞了好久了,指点。我自己很菜,很菜,所以指点下!万分感谢,给你磕头了
要求是:1、学生基本信息录入:学生入学时,可批量录入学生的基本信息;
说明:学生学分信息主要包括:学号、姓名、专业、班级、各大类课程学分、总学分等。其中,学号、姓名、专业、班级为基本信息,其余项可设为0值。
2、学生学分录入:每学期把学生获得的各类学分录入并自动累加。
提示:先选择第几学期,然后录入学生获得的各类别学分,并自动按类别累加。
3、学分统计:统计并显示指定学期学生已获得的各大类课程学分和总学分

我把遇到的那个bug的内容提了出来,问题就在这。
我把代码那个对应的函数模块也重新提出来了。
!我的问题是:
1..给结构体 依次单个输入赋值并打印没用问题,连续给结构体赋值并打印就出错,(除了第一个人没有出错,接下来的人,要么学号不是对应的,姓名和专业要么是空格,要么是白方框。)

img

2.在连续输入多个人的信息后,再输入他们对应的成绩,除了第一个人的会有对应的名字,后面的人就有错误,单个输入一个人信息后在输入成绩就不会有错误。
(我先连续输入4个人,他们对应的信息都是1111,2222,3333,4444),但是输入成绩除了第一个人是姓名,其他的要是是空白,要么是方框!

img

3.我选择3,在输入<8学期的数字,打印的成绩没有错误,,但是,打印第8个学期已获得的成绩,有两个数字会有错误,应该是地址?
(如第一张图的第8 学期,学号本来是3的它打印16,那行)
请告诉指点一下,万分感谢,涨工资,头发常在!!
我用的是VS写的,一开始内存太大了,溢出了我就先把栈给手动增加了,后面在写的动态的内存。下面是那几个功能相关的代码,指点,笨蛋吧。感谢感谢!

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

#define max_name 10
#define max_profession 10
#define max_class 10
#define Max 10
struct m {
    int mm[6];//各学期的成绩

};

typedef struct Peoinfo {

    int num;//学号
    char name[max_name];
    char profession[max_profession];//专业
    char classs[max_class];
    int score[6];//各科目每学期的分数
    int sum[6];//各科目累加总分
    int Allsum;//全部总分
    struct m term[8];
}Peoinfo;

typedef struct GPA {
    Peoinfo data[Max];//存放添加进来的人的信息
    int sz;//记录存放当前学分系统中的有效信息个数
}GPA;

void Initinfo(GPA* pc) {

    pc->sz = 0;
    //memsrt() 函数,内存设置
    memset(pc->data, 0, sizeof(pc->data));
    //这个使data结构体全部初始化为0
}
void Addinfo(GPA* pc);
void Showstu(GPA* pc);
void ScoreAdd(GPA* pc);

int main() {

    GPA info;
    Initinfo(&info);//初始化结构体基本信息
    int input;
    do {
        printf("请选择:>");
        scanf("%d", &input);
        switch (input) {
        case 1:
            Addinfo(&info);
            printf("1111");
            break;
        case 2:
            ScoreAdd(&info);
            printf("4444");
            break;
        case 3:
            Showstu(&info);
            printf("4444");
            break;
        default:
            printf("error");
            break;
        }
    } while (input);
    return 0;
}

//增加学生信息
void Addinfo(GPA* pc) {



    printf("输入学号\n");
    scanf("%d", &pc->data[pc->sz].num);
    printf("输入姓名\n");
    scanf("%s", pc->data[pc->sz].name);
    printf("输入专业\n");
    scanf("%s", pc->data[pc->sz].profession);
    printf("输入班级\n");
    scanf("%s", pc->data[pc->sz].classs);
    pc->sz++;//个数增加
    printf("增加成功\n");
}

//累加的成绩
void allsum(int* sum) {


    printf("  通识类     课程成绩=%d\n", sum[0]);
    printf("专业基础类   课程成绩=%d\n", sum[1]);
    printf("  专业类     课程成绩=%d\n", sum[2]);
    printf("  选修类     课程成绩=%d\n", sum[3]);
    printf("  人文类     课程成绩=%d\n", sum[4]);
    printf("  实践类     课程成绩=%d\n", sum[5]);

    printf("\n");
}

//
void ScoreAdd(GPA* pc) {
    int a;//8个学期
    int q;//具体学期分数和

    int nsum;
    static int  i = 0;//第几个人
    //i <= pc->sz;
    printf("\n");
    printf("\n");


    printf("输入 %s   同学的各学期成绩\n", pc->data[i].name);//保持姓名和学分对应

    printf("请输入8个学期的成绩\n");


    if (/*pc->sz!= ||*/ pc->sz == 0)
        printf("错误!请重新输入\n");
    else {

        printf("输入8学期的成绩\n");
        for (a = 1; a <= 8; a++) {
            //8学期的成绩
            printf("\n");
            printf("\n");
            printf("****第%d学期的成绩****\n", a);
            printf("输入 通识类 课程成绩\n");
            scanf("%d", &pc->data[i].score[0]);

            printf("输入 专业基础类 课程成绩\n");
            scanf("%d", &pc->data[i].score[1]);

            printf("输入 专业类 课程成绩\n");
            scanf("%d", &pc->data[i].score[2]);

            printf("输入 选修类 课程成绩\n");
            scanf("%d", &pc->data[i].score[3]);

            printf("输入 人文类 课程成绩\n");
            scanf("%d", &pc->data[i].score[4]);

            printf("输入 实践类 课程成绩\n");
            scanf("%d", &pc->data[i].score[5]);

            printf("\n");
            printf("\n");
        
                for (int b = 0; b < 6; b++) {

                    pc->data[i].sum[b] += pc->data[i].score[b];
                }//单科总分

            for (int b = 0; b < 6; b++) {

                pc->data[i].term[a].mm[b] = pc->data[i].sum[b];
            }//第x学期的已获得的六科目各获得的成绩

            printf("%s第%d学期已经获得的成绩\n", pc->data[i].name, a);
            printf("通识类\t专业基础类\t专业类\t选修类\t人文类\t实践类\n");
            printf(" %d\t    % d\t\t% d\t % d\t % d\t % d\n",
                pc->data[i].term[a].mm[0],
                pc->data[i].term[a].mm[1],
                pc->data[i].term[a].mm[2],
                pc->data[i].term[a].mm[3],
                pc->data[i].term[a].mm[4],
                pc->data[i].term[a].mm[5]);

            for (nsum = 0, q = 0; q < 6; q++) {

                nsum += pc->data[i].term[a].mm[q];//总成绩累加    
                pc->data[i].Allsum = nsum;
            }
        }
        printf("------------------------------------------------\n");
        printf("****%s同学的各学期成绩****\n", pc->data[i].name);

        allsum(pc->data[i].sum);//总成绩    
        i++;
        printf("------------------------------------------------\n");
    }
    printf("\n");
    printf("\n");

}

void Showstu(GPA* pc) {
    //学分统计
    int a = 0;
    int time = 8;
    printf("统计指定学期学生 已获得的各大类课程学分\n");
    printf("输入指定学期\n");
    scanf("%d", &time);//输入指定的学期
    printf("\n");
    printf("\n");
    printf("学号\t姓名\t专业\t班级\t通识类\t    专业基础类\t专业类\t选修类\t人文类\t实践类\t总分\n");
    for (a = 0; a < pc->sz; a++) {
        printf("%d\t%s\t%s\t%s\t %d\t\t%d\t  %d\t %d\t%d\t%d\t%d\n",
            pc->data[a].num,
            pc->data[a].name,
            pc->data[a].profession,
            pc->data[a].classs,
            pc->data[a].term[time].mm[0],
            pc->data[a].term[time].mm[1],
            pc->data[a].term[time].mm[2],
            pc->data[a].term[time].mm[3],
            pc->data[a].term[time].mm[4],
            pc->data[a].term[time].mm[5],
            pc->data[a].term[time].mm[0] + pc->data[a].term[time].mm[1] + pc->data[a].term[time].mm[2] + pc->data[a].term[time].mm[3] + pc->data[a].term[time].mm[4] + pc->data[a].term[time].mm[5]
            //指定学期的总成绩和
        );
        //统计所有学生各科目成绩
    }
    printf("\n");

}



代码的主要问题,在void ScoreAdd(GPA* pc) 函数里,对 struct m term[8]; 数组的越界操作,修改改动处见注释 “ // 修改 ” 语句,修改完善如下,供参考:

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

#define max_name 10
#define max_profession 10
#define max_class 10
#define Max 10

// 修改
#define len_int_fmt  "10"
#define max_name_fmt "10"
#define max_profession_fmt "10"
#define max_class_fmt  "12"


// 修改
#define print_alltitle_fmt  "%-" len_int_fmt "s %-" max_name_fmt "s %-" max_profession_fmt "s %-"  \
                                 max_class_fmt "s %-" len_int_fmt "s %-" len_int_fmt "s %-" len_int_fmt "s %-"  \
                                 len_int_fmt "s %-" len_int_fmt "s %-" len_int_fmt "s %-" len_int_fmt "s\n"
// 修改
#define print_alldata_fmt   "%-" len_int_fmt "d %-" max_name_fmt "s %-" max_profession_fmt "s %-"  \
                                 max_class_fmt "s %-" len_int_fmt "d %-" len_int_fmt "d %-" len_int_fmt "d %-"   \
                                 len_int_fmt "d %-" len_int_fmt "d %-" len_int_fmt "d %-" len_int_fmt "d\n"
// 修改
#define print_titletxt_fmt   "学号", "姓名", "专业", "班级", "通识类", "专业基础类", "专业类", "选修类", "人文类", "实践类", "总分"

struct   m {
    int mm[6];//各学期的成绩
};

typedef struct Peoinfo {

    int  num;//学号
    char name[max_name];
    char profession[max_profession];//专业
    char classs[max_class];
    int  score[6];//各科目每学期的分数
    int  sum[6];//各科目累加总分
    int  Allsum;//全部总分
    struct m term[8];
}Peoinfo;

typedef struct GPA {
    Peoinfo data[Max];//存放添加进来的人的信息
    int sz;//记录存放当前学分系统中的有效信息个数
}GPA;

void Initinfo(GPA* pc) {

    pc->sz = 0;
    //memsrt() 函数,内存设置
    memset(pc->data, 0, sizeof(pc->data));
    //这个使data结构体全部初始化为0
}
void Addinfo(GPA* pc);
void Showstu(GPA* pc);
void ScoreAdd(GPA* pc);

int main() {

    GPA info;
    Initinfo(&info);//初始化结构体基本信息
    int input;
    do {
        printf("请选择:>");
        scanf("%d", &input);
        switch (input) {
        case 1:
            Addinfo(&info);
            printf("1111");
            break;
        case 2:
            ScoreAdd(&info);
            printf("4444");
            break;
        case 3:
            Showstu(&info);
            printf("4444");
            break;
        default:
            printf("error");
            break;
        }
    } while (input);
    return 0;
}

//增加学生信息
void Addinfo(GPA* pc) {

    printf("输入学号\n");
    scanf("%d", &pc->data[pc->sz].num);
    printf("输入姓名\n");
    scanf("%s", pc->data[pc->sz].name);
    printf("输入专业\n");
    scanf("%s", pc->data[pc->sz].profession);
    printf("输入班级\n");
    scanf("%s", pc->data[pc->sz].classs);
    pc->sz++;//个数增加
    printf("增加成功\n");
}

//累加的成绩
void allsum(int* sum) {


    printf("  通识类     课程成绩=%d\n", sum[0]);
    printf("专业基础类   课程成绩=%d\n", sum[1]);
    printf("  专业类     课程成绩=%d\n", sum[2]);
    printf("  选修类     课程成绩=%d\n", sum[3]);
    printf("  人文类     课程成绩=%d\n", sum[4]);
    printf("  实践类     课程成绩=%d\n", sum[5]);

    printf("\n");
}

//
void ScoreAdd(GPA* pc) {
    int a;//8个学期
    int q;//具体学期分数和

    int nsum;
    static int  i = 0;//第几个人
    printf("\n");
    printf("\n");
    if (pc->sz == 0)   return;   // 修改 
    if ( pc->sz <= i) {          // 修改
        printf("提示:最后一个学生 %s 的分数已添加完成!\n", pc->data[i-1].name); // 修改
        return;
    }
    else {
        printf("输入 %s 同学的各学期成绩\n", pc->data[i].name);//保持姓名和学分对应
        printf("请输入8个学期的成绩\n");
        for (a = 1; a <= 8; a++) {       //8个学期,a 从 1 开始执行到 8     修改
            //8学期的成绩
            printf("\n");
            printf("\n");
            printf("****第%d学期的成绩****\n", a);
            printf("输入 通识类 课程成绩\n");
            scanf("%d", &pc->data[i].score[0]);

            printf("输入 专业基础类 课程成绩\n");
            scanf("%d", &pc->data[i].score[1]);

            printf("输入 专业类 课程成绩\n");
            scanf("%d", &pc->data[i].score[2]);

            printf("输入 选修类 课程成绩\n");
            scanf("%d", &pc->data[i].score[3]);

            printf("输入 人文类 课程成绩\n");
            scanf("%d", &pc->data[i].score[4]);

            printf("输入 实践类 课程成绩\n");
            scanf("%d", &pc->data[i].score[5]);

            printf("\n");
            printf("\n");

            for (int b = 0; b < 6; b++) {

                pc->data[i].sum[b] += pc->data[i].score[b];
            }//单科总分

            for (int b = 0; b < 6; b++) {
                                                                     
                pc->data[i].term[a - 1].mm[b] = pc->data[i].sum[b]; // 修改:这里对term[] 数组操作越界了,应改为:a-1 
                //pc->data[i].term[a].mm[b] = pc->data[i].sum[b];
            }//第x学期的已获得的六科目各获得的成绩

            printf("%s第%d学期已经获得的成绩\n", pc->data[i].name, a);
            printf("通识类\t专业基础类\t专业类\t选修类\t人文类\t实践类\n");
            printf(" %d\t    % d\t\t% d\t % d\t % d\t % d\n",
                pc->data[i].term[a-1].mm[0],    //pc->data[i].term[a].mm[0], // 修改
                pc->data[i].term[a-1].mm[1],    //pc->data[i].term[a].mm[1], // 修改
                pc->data[i].term[a-1].mm[2],    //pc->data[i].term[a].mm[2], // 修改
                pc->data[i].term[a-1].mm[3],    //pc->data[i].term[a].mm[3], // 修改
                pc->data[i].term[a-1].mm[4],    //pc->data[i].term[a].mm[4], // 修改
                pc->data[i].term[a-1].mm[5]);   //pc->data[i].term[a].mm[5]);// 修改

            for (nsum = 0, q = 0; q < 6; q++) {

                nsum += pc->data[i].term[a-1].mm[q];//总成绩累加 //nsum += pc->data[i].term[a].mm[q];  修改   
                pc->data[i].Allsum = nsum;
            }
        }
        printf("------------------------------------------------\n");
        printf("****%s同学的各学期成绩****\n", pc->data[i].name);

        allsum(pc->data[i].sum);//总成绩    
        i++;
        printf("------------------------------------------------\n");
    }
    printf("\n");
    printf("\n");

}

void Showstu(GPA* pc) {
    //学分统计
    int a = 0;
    int time = 8;
    printf("统计指定学期学生 已获得的各大类课程学分\n");
    do {                                     // 修改
        printf("输入指定学期\n");
        scanf("%d", &time);//输入指定的学期
    } while (time < 1 || time > 8);          // 修改     
    printf("\n");
    printf("\n");
    printf(print_alltitle_fmt , print_titletxt_fmt); // 修改
    for (a = 0; a < pc->sz; a++) {
        printf(print_alldata_fmt,    // 修改
            pc->data[a].num,
            pc->data[a].name,
            pc->data[a].profession,
            pc->data[a].classs,
            pc->data[a].term[time].mm[0],
            pc->data[a].term[time].mm[1],
            pc->data[a].term[time].mm[2],
            pc->data[a].term[time].mm[3],
            pc->data[a].term[time].mm[4],
            pc->data[a].term[time].mm[5],
            pc->data[a].term[time].mm[0] + pc->data[a].term[time].mm[1] + pc->data[a].term[time].mm[2] + 
            pc->data[a].term[time].mm[3] + pc->data[a].term[time].mm[4] + pc->data[a].term[time].mm[5]
            //指定学期的总成绩和
        );
        //统计所有学生各科目成绩
    }
    printf("\n");
}
不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/1064451
  • 除此之外, 这篇博客: C语言实现八大排序算法详解及其性能之间的中的 我们老师给我们花了100个星星的重要,那就是非常重要,快速排序。名字就很嚣张。。。言归正传,快排采用了分治算法。把大问题,分解成小问题。首先我们先找一个基准值,基准值的寻找法,有很多,这里我先用一个取边上值得方法,找到基准值以后呢拿着这个基准值和所有数组比较,使这个数组中比基准值小的都放左边,比基准值大的都放到右边,然后就把原来数组分成三块,中间基准值,左边都是比它小的,右边都是比它大的。然后这两个数组,继续分,一直分。直到他的终止条件,也就是小数组有序了就停止,那么什么时候有序停止呢?小区间长度为1或者长度为0的时候,就是有序了。所有小数组都有序了,那么就是整个数组有序了。只是原理,那么问题,又来了,怎么放左放右呢?我目前会三种。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    算法思想


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^