c考勤管理系统的处理

在删除学生信息时,例如删除学生学号为01的学生信息,该学生的考勤信息只能删除其中的一条,其他的无法删除是为什么?

//学生类
#include <windows.h>
#include<iostream>
#include<iomanip>
#include<fstream>
#include<cstring>
using namespace std;
#define MAX 100

//学生基本信息
class Student
{
private:
    int num;    //学生学号    
    char name[20];//姓名
    int age;//年龄
    char sex[6];//性别
    char addr[20];//班级
    int times; //缺课次数

public:
    Student();
    void set_num(int num);
    void set_name(char name[20]);
    void set_age(int age);
    void set_sex(char sex[6]);
    void set_addr(char addr[20]);
    void set_times(int times);
    int get_num();
    char* get_name();
    int get_age();
    char* get_sex();
    char* get_addr();
    int get_times();
};
//考勤基本信息
class Absence {
private:
    int num1;    // 学号    
    char name1[20];//名字
    char addr1[20];//班级

    char date[30];   //缺课日期
    int n;//第几节课
    char cname[20];//缺课名字
    char ckind[20];//缺课类型

public:
    Absence();
    void set_num1(int num1);
    void set_name1(char name1[20]);
    void set_addr1(char addr1[20]);
    void set_date(char date[30]);
    void set_n(int n);
    void set_cname(char cname[20]);
    void set_ckind(char ckind[20]);

    int get_num1();
    char* get_name1();
    char* get_addr1();
    char* get_date();
    int get_n();
    char* get_cname();
    char* get_ckind();

};

Student::Student()
{
    this->num = 0;
    this->name[20] = ' ';
    this->age = 20;
    this->sex[6] = 'man';
    this->addr[20] = ' ';
    this->times = 0;
}

Absence::Absence()
{
    this->num1 = 0;
    this->name1[20] = ' ';
    this->addr1[20] = ' ';
    this->date[30];
    this->n = 1;
    this->cname[20] = 'c++';
    this->ckind[20] = ' ';
}

void Student::set_num(int num)
{
    this->num = num;
}
void Student::set_name(char name[20])
{
    memcpy(this->name, name, sizeof(this->name));//memcpy为内存拷贝函数
}
void Student::set_age(int age)
{
    this->age = age;
}
void Student::set_sex(char sex[6])
{
    memcpy(this->sex, sex, sizeof(this->sex));
}
void Student::set_addr(char addr[20])
{
    memcpy(this->addr, addr, sizeof(this->addr));
}
void Student::set_times(int times) //设置学生缺课次数
{
    this->times = times;
}

int Student::get_num()
{
    return this->num;
}
char* Student::get_name()
{
    return this->name;
}
int Student::get_age()
{
    return this->age;
}
char* Student::get_sex()
{
    return this->sex;
}
char* Student::get_addr()
{
    return this->addr;
}
int Student::get_times()
{
    return this->times;
}

//以下为Absence类成员函数
void Absence::set_num1(int num1)
{
    this->num1 = num1;
}
void Absence::set_name1(char name1[20])
{
    memcpy(this->name1, name1, sizeof(this->name1));
}
void Absence::set_addr1(char addr1[20])
{
    memcpy(this->addr1, addr1, sizeof(this->addr1));
}
void Absence::set_date(char date[4])
{
    memcpy(this->date, date, sizeof(this->date));
}
void Absence::set_n(int n)
{
    this->n = n;
}
void Absence::set_cname(char cname[20])
{
    memcpy(this->cname, cname, sizeof(this->cname));
}
void Absence::set_ckind(char ckind[20])
{
    memcpy(this->ckind, ckind, sizeof(this->ckind));
}

//获取考勤信息
int Absence::get_num1()
{
    return this->num1;
}
char* Absence::get_name1()
{
    return this->name1;
}
char* Absence::get_addr1()
{
    return this->addr1;
}
char* Absence::get_date()
{
    return this->date;
}
int Absence::get_n()
{
    return this->n;
}
char* Absence::get_cname()
{
    return this->cname;
}
char* Absence::get_ckind()
{
    return this->ckind;
}

int iFile(Student b[MAX], Absence a[MAX], int& i, int& j, int& z, int& o)              //读取信息
{
    int g, k;
    ifstream file1, file2, file3, file4;
    file2.open("D:\\序数表.txt", ios::in); //记录人数  判断人数是否为0 
    file2 >> z; //z保存序数值
    file4.open("D:\\缺勤记录序数表.txt", ios::in); //记录人数  判断人数是否为0 
    file4 >> o; //z保存序数值
    i = z;
    j = o;
    if (z == 0) //没有信息无需读取
        return 1;
    file1.open("D:\\学生信息表.txt", ios::in); //记录学生信息
    for (g = 0; g < i; g++) //将学生信息循环输入
    {
        int t1;
        char t2[20];
        int t3;
        char t4[6];
        char t5[20];
        int t6;
        file1 >> t1;
        file1 >> t2;
        file1 >> t3;
        file1 >> t4;
        file1 >> t5;
        file1 >> t6;
        b[g].set_num(t1);
        b[g].set_name(t2);
        b[g].set_age(t3);
        b[g].set_sex(t4);
        b[g].set_addr(t5);
        b[g].set_times(t6);
    }
    file1.close();
    if (o == 0) //没有信息无需读取
        return 1;
    file3.open("D:\\缺勤信息表.txt", ios::in);
    for (k = 0; k < j; k++)
    {
        int a1;
        char a2[20];
        char a3[20];
        char a4[30];
        int a5;
        char a6[20];
        char a7[20];
        file3 >> a1;
        file3 >> a2;
        file3 >> a3;
        file3 >> a4;
        file3 >> a5;
        file3 >> a6;
        file3 >> a7;
        a[k].set_num1(a1);
        a[k].set_name1(a2);
        a[k].set_addr1(a3);
        a[k].set_date(a4);
        a[k].set_n(a5);
        a[k].set_cname(a6);
        a[k].set_ckind(a7);

    }
    file3.close();
    return 1;
}

void oFile(Student b[MAX], Absence a[MAX], int i, int j, int z, int o)  //录入信息
{
    int g, k;
    ofstream file1, file2, file3, file4;                //利用ofstream类的构造函数创建一个文件输出流对象来打开文件
    file2.open("D:\\序数表.txt", ios::out); //打开序数表
    file2 << i; //保存当前学生人数
    file4.open("D:\\缺勤记录序数表.txt", ios::out); //打开序数表
    file4 << j; //保存当前学生人数
    file1.open("D:\\学生信息表.txt", ios::out); //打开学生信息表
    for (g = 0; g < i; g++)
    {
        int t1 = b[g].get_num();
        string t2 = b[g].get_name();
        int t3 = b[g].get_age();
        string t4 = b[g].get_sex();
        string t5 = b[g].get_addr();
        int t6 = b[g].get_times();
        file1 << t1 << endl;
        file1 << t2 << endl;
        file1 << t3 << endl;
        file1 << t4 << endl;
        file1 << t5 << endl;
        file1 << t6 << endl;
    }
    file1.close();
    file3.open("D:\\缺勤信息表.txt", ios::out);
    for (k = 0; k < j; k++)
    {
        int a1 = a[k].get_num1();
        string a2 = a[k].get_name1();
        string a3 = a[k].get_addr1();
        string a4 = a[k].get_date();
        int a5 = a[k].get_n();
        string a6 = a[k].get_cname();
        string a7 = a[k].get_ckind();
        file3 << a1 << endl;
        file3 << a2 << endl;
        file3 << a3 << endl;
        file3 << a4 << endl;
        file3 << a5 << endl;
        file3 << a6 << endl;
        file3 << a7 << endl;
    }
    file3.close();
}


int _Input_Student(Student b[100], int& i, int z)// 1.录入学生基本信息
{
    int g = 0, k = 0;
    char n;
    char a;
    for (i = z; i < MAX;) //Z是记录序数
    {
        cout << "===================================" << endl;
        cout << "输入该学生的学号:";
        int t1;
        cin >> t1;
        if (i != 0)//i不等于0说明已存有学生信息,需进行判断学生学号是否重复
        {
            for (g = 0; g < i; g++)
            {
                int c1 = b[g].get_num();
                if (c1 == t1)
                {
                    cout << "错误!学生学号重复录入!输入任意值返回菜单!" << endl;
                    cin >> n;
                    system("cls");
                    return 1;
                }
                else
                {
                    continue; //继续循环
                }
            }
        }
        b[i].set_num(t1);
        cout << "输入该学生的姓名:";
        char t2[20];
        cin >> t2;
        b[i].set_name(t2);
        cout << "输入该学生的年龄:";
        int t3;
        cin >> t3;
        b[i].set_age(t3);
        while (1)
        {
            cout << "输入该学生的性别(男/女):";
            char t4[6];
            cin >> t4;
            if ((strcmp(t4, "男") == 0) || (strcmp(t4, "女") == 0)) //判断用户输入的数是否正确,strcmp用于与输入的数据做比较,若两字符串相同,返回结果等于0
            {
                b[i].set_sex(t4);
                break;
            }
            else
                cout << "您输入的信息有误!请输入 男 或 女 。" << endl;
        }
        cout << "输入该学生的班级:";
        char t5[20];
        cin >> t5;
        b[i].set_addr(t5);
        cout << "输入该学生的缺课次数: ";
        int t6;
        cin >> t6;
        b[i].set_times(t6);
        cout << "====================================" << endl;
        cout << "您是否要继续输入(y/n) :";
        i++;
        while (1)
        {
            cin >> a;
            if (a == 'y' || a == 'Y')
            {
                system("cls");
                break;//跳出该循环,继续录入信息
            }
            if (a == 'n' || a == 'N')
            {
                system("cls");
                return 1;//返回菜单
            }
            else
            {
                cout << "您输入的数据有误,请重新输入(y/n):" << endl;
            }
        }

    }
    return 1;
}

int _Input_Absence(Student b[100], Absence a[MAX], int& i, int& j, int& z, int& o)// 录入考勤信息
{
    int g = 0, k = 0;
    char n;
    char m;
    for (j = o; j < MAX;) //o是记录序数
    {
        cout << "===================================" << endl;
        cout << "输入该学生的学号:";
        int a1;
        cin >> a1;
        for (g = 0; g < z; g++)
        {
            int t1 = b[g].get_num();
            if (a1 == t1)//如果学生信息表中,有与输入的学号相同的,则进入循环
            {
                k++;//记录已找到学生信息
                int t = b[g].get_times();//获取该学生的缺课次数
                t++;//录入信息,自增记录
                b[g].set_times(t);//把值返还
                break;//找到了可以直接退出循环
            }

        }
        if (k == 0)//k=0就是没有找到学生的信息
        {
            cout << "未找到该学生的基本信息,请确保该学生信息已录入!" << endl;
            cout << "按任意键返回" << endl;
            cin >> n;
            system("cls");
            return 1;
        }
        a[j].set_num1(a1);
        cout << "输入该学生的姓名:";
        char a2[20];
        cin >> a2;
        a[j].set_name1(a2);
        for (int g = 0; g < z; g++)
        {
            int t1 = b[g].get_num();
            if (a1 == t1)
            {
                string c2 = b[g].get_name();
                if (c2 != a2)
                {
                    cout << "错误!学号和姓名要唯一!输入任意键返回菜单!" << endl;
                    cin >> n;
                    system("cls");
                    return 1;
                }
            }
        }
        cout << "输入该学生的班级:";
        char a3[20];
        cin >> a3;
        a[j].set_addr1(a3);
        cout << "输入该学生的缺勤日期(年-月-日):";
        char a4[20];
        cin >> a4;
        a[j].set_date(a4);
        cout << "输入该学生缺勤是第几节课:";
        int a5;
        cin >> a5;
        a[j].set_n(a5);
        cout << "输入该学生缺勤课程名称:";
        char a6[20];
        cin >> a6;
        a[j].set_cname(a6);
        while (1)
        {
            cout << "输入该学生缺勤类型(迟到/早退/请假/旷课):";
            char a7[20];
            cin >> a7;
            if ((strcmp(a7, "迟到") == 0) || (strcmp(a7, "早退") == 0) || (strcmp(a7, "请假") == 0) || (strcmp(a7, "旷课") == 0))
            {
                a[j].set_ckind(a7);
                break;
            }
            else
                cout << "您输入的信息有误!请输入 迟到/早退/请假/旷课 。" << endl;
        }
        cout << "====================================" << endl;
        cout << "您是否要继续输入(y/n) :";
        j++;
        while (1)
        {
            cin >> m;
            if (m == 'y' || m == 'Y')
            {
                system("cls");
                break;
            }
            if (m == 'n' || m == 'N')
            {
                system("cls");
                return 1;
            }
            else
            {
                cout << "您输入的数据有误,请重新输入(y/n):" << endl;
            }
        }

    }
    return 1;
}



int _Delete(Student b[100], Absence a[MAX], int& i, int& j)//删除学生信息
{
    int n;
    if (i == 0)
    {
        cout << "暂无数据!" << endl;
        cout << "回复任意键返回:";
        cin >> n;
        system("cls");
        return 1;
    }

    while (1)
    {
        cout << "==========================================================================================" << endl;
        cout << "学生基本信息表:" << endl;
        cout << "序数\t\t学       号|\t|姓       名|\t|年       龄|\t|性       别|\t|班       级|\t|缺 勤 次 数|\t" << endl;
        for (int g = 0; g < i; g++)
        {
            int t1 = b[g].get_num();
            string t2 = b[g].get_name();
            int t3 = b[g].get_age();
            string t4 = b[g].get_sex();
            string t5 = b[g].get_addr();
            int t6 = b[g].get_times();
            cout << setw(2) << g + 1 << "\t\t" << setw(11) << t1 << "\t" << setw(12) << t2 << "\t" << setw(12) << t3 << "\t" << setw(12) << t4 << "\t" << setw(12) << t5 << "\t" << setw(12) << t6 << endl;
        }
        cout << "==========================================================================================" << endl;
        cout << "请输入需要消除的学生的序数或返回主页面(序数/0)" << endl;
        int k;
        while (1)
        {
            cin >> k;
            if (k == 0)
            {
                system("cls");
                return 1;
            }
            if (k > i)//i为学生总数
                cout << "您输入的信息有误!请重新输入(序数/0):";
            else
            {
                int t1 = b[k - 1].get_num();//获得所删除学生的学号
                int c3 = 0;
                for (int k1 = 0; k1 < j; k1++)//j为考勤信息总数
                {
                    int a1 = a[k1].get_num1();

                    if (t1 == a1)//查找考勤信息里该学生的学号
                    {
                        for (int k2 = k1; k2 <= j; k2++)
                            a[k2] = a[k2 + 1];//信息覆盖
                        c3++;
                    }
                    else
                        continue;
                }
                j = c3;//
                for (; k <= i; k++)//学生信息覆盖
                    b[k - 1] = b[k];
                i--;//学生人数减一

                system("cls");
                cout << "修改后的:" << endl;
                break;
            }
        }
    }
}


int _Display(Student b[MAX], Absence a[MAX], int i, int j)//显示当前学生信息
{
    char n;
    int g, k;
    if (i == 0)
    {
        cout << "暂无数据!" << endl;
        cout << "回复任意键返回:";
        cin >> n;
        system("cls");
        return 1;
    }
    cout << "==========================================================================================" << endl;
    cout << "学生基本信息表:" << endl;
    cout << "序数\t\t学       号|\t|姓       名|\t|年       龄|\t|性       别|\t|班       级|\t|缺 勤 次 数|\t" << endl;
    for (g = 0; g < i; g++)
    {
        int t1 = b[g].get_num();
        string t2 = b[g].get_name();
        int t3 = b[g].get_age();
        string t4 = b[g].get_sex();
        string t5 = b[g].get_addr();
        int t6 = b[g].get_times();
        cout << setw(2) << g + 1 << "\t\t" << setw(11) << t1 << "\t" << setw(12) << t2 << "\t" << setw(12) << t3 << "\t" << setw(12) << t4 << "\t" << setw(12) << t5 << "\t" << setw(12) << t6 << endl;
    }
    cout << "==========================================================================================" << endl;
    cout << "学生考勤信息表:" << endl;
    cout << "序数\t\t学       号|\t|姓       名|\t|班       级|\t|缺 勤 日 期|\t|第 几 节 课|\t|缺 勤 课 名|\t|缺 勤 类 型|\t" << endl;
    if (j == 0)
    {
        cout << "暂无数据!" << endl;
    }
    for (k = 0; k < j; k++)
    {
        int a1 = a[k].get_num1();
        string a2 = a[k].get_name1();
        string a3 = a[k].get_addr1();
        string a4 = a[k].get_date();
        int a5 = a[k].get_n();
        string a6 = a[k].get_cname();
        string a7 = a[k].get_ckind();
        cout << setw(2) << k + 1 << "\t\t" << setw(11) << a1 << "\t" << setw(12) << a2 << "\t" << setw(12) << a3 << "\t" << setw(12) << a4 << "\t" << setw(12) << a5 << "\t" << setw(12) << a6 << "\t" << setw(12) << a7 << endl;
    }
    cout << "==========================================================================================" << endl;
    cout << "回复任意键返回:";
    cin >> n;
    system("cls");
    return 1;
}

int main()
{
    int i, z = 0, j = 0, o = 0;
    char n, c;
    Student x[MAX];
    Absence y[MAX];
    iFile(x, y, i, j, z, o);
    while (1)
    {
        cout << "**************学生信息管理系统**************" << endl;
        cout << "               1.录入学生基本信息" << endl;
        cout << "               2.录入学生考勤信息" << endl;
        cout << "               3.显示当前学生信息" << endl;
        cout << "               4.修改学生信息(tips:请手动保存)" << endl;
        cout << "               5.删除学生信息(tips:请手动保存)" << endl;
        cout << "               9.保存文件" << endl;
        cout << "               0.退出管理系统" << endl;
        cout << "********************************************" << endl;
        cout << "请选择序号:" << endl;
        cin >> n;
        switch (n)
        {
        case '1':system("cls"); iFile(x, y, i, j, z, o); _Input_Student(x, i, z); oFile(x, y, i, j, z, o); break;
        case '2':system("cls"); iFile(x, y, i, j, z, o); _Input_Absence(x, y, i, j, z, o); oFile(x, y, i, j, z, o); break;
        case '3':system("cls"); _Display(x, y, i, j); break;
        
        case '5':system("cls"); _Delete(x, y, i, j); break;
        case '9':system("cls"); oFile(x, y, i, j, z, o); cout << "以保存,输入任意字符返回主菜单:"; cin >> c; system("cls"); break;
        case '0':exit(0);
        default:system("cls"); cout << "您输入的序号有误!\n输入任意字符返回主菜单"; cin >> c; system("cls");
        }
    }
    return 0;
}

好的,我来帮您修改一下这段代码中存在的问题。

首先,在删除一个学生时,可能对应多个考勤记录。因此,需要在找到该学生对应的考勤记录后,将其后续的考勤记录依次前移。同时,还需要把考勤信息总数 j 减去被删除的考勤记录数,以保证后续操作不会误读已经被删除的考勤记录。

其次,当删除一个学生的信息时,需要仔细考虑该操作对其它学生信息及考勤记录的引用是否会发生影响。在该代码中,删除一个学生后,该学生信息后面的所有学生信息都会向前移动一个位置,从而导致它们原本对应的考勤记录的位置也发生了改变。因此,我们需要重新更新所有考勤记录中的学号,使用新的学号进行匹配,才能保证数据的正确性。

下面是修改后的代码:

int Delete(Student b[100], Absence a[MAX], int& i, int& j) {
    int n;
    if (i == 0) {
        cout << "暂无数据!" << endl;
        cout << "回复任意键返回:";
        cin >> n;
        system("cls");
        return 1;
    }

    while (1) {
        cout << "==========================================================================================" << endl;
        cout << "学生基本信息表:" << endl;
        cout << "序数\t\t学       号|\t|姓       名|\t|年       龄|\t|性       别|\t|班       级|\t|缺 勤 次 数|\t" << endl;
        for (int g = 0; g < i; g++) {
            int t1 = b[g].get_num();
            string t2 = b[g].get_name();
            int t3 = b[g].get_age();
            string t4 = b[g].get_sex();
            string t5 = b[g].get_addr();
            int t6 = b[g].get_times();
            cout << setw(2) << g + 1 << "\t\t" << setw(11) << t1 << "\t" << setw(12) << t2 << "\t" << setw(12) << t3 << "\t" << setw(12) << t4 << "\t" << setw(12) << t5 << "\t" << setw(12) << t6 << endl;
        }
        cout << "==========================================================================================" << endl;
        cout << "请输入需要消除的学生的序数或返回主页面(序数/0)" << endl;
        int k;
        while (1) {
            cin >> k;
            if (k == 0) {
                system("cls");
                return 1;
            }
            if (k > i) {//i为学生总数
                cout << "您输入的信息有误!请重新输入(序数/0):";
            }
            else {
                int t1 = b[k - 1].get_num();//获得所删除学生的学号
                int c3 = 0;
                for (int k1 = 0; k1 < j; k1++) {//j为考勤信息总数
                    if (t1 == a[k1].get_num1()) {//查找所有对应该学号的考勤记录
                        for (int k2 = k1; k2 < j - 1; k2++) {
                            //删除考勤记录并将被删除的记录后面的记录依次前移
                            a[k2] = a[k2 + 1];
                            a[k2].set_num1(a[k2].get_num1() - 1);//更新考勤记录中的学号
                        }
                        c3++;
                        j--;//考勤记录总数减一
                    }
                }
                for (; k <= i - 1; k++) {//学生信息覆盖
                    b[k - 1] = b[k];
                    for (int k1 = 0; k1 < j; k1++) {
                        //更新所有考勤记录中的学号
                        if (b[k - 1].get_num() == a[k1].get_num1()) {
                            a[k1].set_num1(k - 1);
                        }
                    }
                }
                i--;//学生人数减一

                system("cls");
                cout << "修改后的:" << endl;
                break;
            }
        }
    }
}

你尝试整合一下,看看是否解决了问题。如果对你有帮助的话,请采纳我,谢谢~