C++之学生考勤系统

  1. 问题描述
    学生信息包括:学号、姓名、性别、年龄、班级等信息
    考勤信息包括:缺课日期、第几节课、课程名称、学生姓名、缺课类型(迟
    到、早退、请假和旷课)。
  2. 功能要求
    基本功能
    (1)添加功能:程序能够添加学生的记录和缺课记录,课提供选择界面供
    用户选择所要添加的类别,添加学生记录时,要求学号要唯一,如果添加了重复
    学号的记录时,则提示数据添加重复并取消添加。
    (2)显示功能:可显示当前系统中所有学生的记录和缺课,每条记录占据
    一行。
    (3)统计功能:能根据学号进行统计,能统计本次输入记录中的信息,也能够统计已存在的文件中的信息
    (4)保存功能:可将当前系统中各类记录存入文件中,存入方式.txt文件。
    (5)退出系统。
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<ctime>
    
    
    #include<fstream>
    #include<istream>
    #include<ostream>
    #include<stdio.h>
    #include<stdlib.h>
    
    
    #define MAX 1000//该系统的容量 可更改
    #pragma warning(disable:4996);
    using namespace std;
    struct student
    {
    	char S_ID[24];
    	char S_name[24];
    	char S_sex[24];
    	char S_age[24];
    	char S_class[24];
    };
    struct Queke
    {
    	char Q_data[24];
    	char Q_diclass[24];
    	char Q_project[24];
    	char Q_sort[24];
    };
    struct Kaoqin
    {
    	Queke que[MAX];
    	student stu[MAX];
    	int K_size = 0;
    };
    
    //定义一个三维数组  这里本来只需要使用一个结构体就可以  但是本人局限于不知道怎么使用结构体数组做函数实参 故此增加了下面一个结构体
    struct shuzu
    {
    	char AA1[9][24];
    };
    struct Shuzu
    {
        shuzu AA[MAX];
    };
    
    int M;//存储在统计时文件的行数
    void menu();
    void addstudent(struct Kaoqin* K);
    void AddStu(struct Kaoqin* K, char ID[24]);
    void showkaoqin(struct Kaoqin* K);
    int LookID(struct Kaoqin* K, char ID[24]);
    void Addque(struct Kaoqin* K, int i);
    void preserve(struct Kaoqin* K);
    void readfile(char* filename, struct Shuzu *A1);
    void tongji(struct Kaoqin* K, char ID[24]);
    int Readfile(char *filename);
    
    char filename[1000];
    
    int main()
    {
    	Kaoqin K1;
    
    	int Number;
    	K1.K_size = 0;
    C2:	menu();
    	cout << "请输入您想要的功能代号:";
    	cin >> Number;
    	switch (Number)
    	{
    	case 1:
    	{
    	C1:			addstudent(&K1);
    		string t;
    		cout << "是否继续添加学生:1 :是;    任意键:否" << endl;
    		cout << "请输入您的选择:";
    		cin >> t;
    		if (t == "1")
    		{
    			goto C1;//该循环用于重复添加多个学生的记录
    		}
    		break;
    	}
    	case 2:
    	{
    		string H_K;
    		showkaoqin(&K1);
    		cout << "输入 1 保留显示,输入任意键退出该显示界面:";
    		cin >> H_K;
    		if (H_K == "1")
    		{
    			break;
    		}
    		else
    		{
    			system("cls");
    			break;
    		}
    	}
    	case 3:
    	{
    		char ID[24];
    		cout << "请输入您想要统计学生缺课信息的学号:";
    		cin >> ID;
    		tongji(&K1,ID);
    		break;
    	}
    	case 4:
    	{
    		preserve(&K1);
    		break;
    	}
    	case 5:
    		system("cls");
    		system("pause");
    		break;
    	}
    	//system("cls");
    	cout << "是否需要执行其他操作:1 是;其他任意键 否" << endl;
    	string R;
    	cin >> R;
    	if (R == "1")
    	{
    		system("cls");//请屏的指令  类比于MATLAB 中的cls
    		goto C2;//这个循环是用于循环操作
    	}
    	else
    	{
    		system("cls");
    		system("pause");
    	}
    	return 0;
    }
    
    //菜单函数  即界面显示的函数
    void menu()
    {
    	cout << "******************************************" << endl;
    	cout << "**      功能代号\t" << "具体功能\t**" << endl;
    	cout << "**                                      **" << endl;
    	cout << "**\t  " << 1 << "\t\t" << "添加功能\t**" << endl;
    	cout << "**\t  " << 2 << "\t\t" << "显示功能\t**" << endl;
    	cout << "**\t  " << 3 << "\t\t" << "统计功能\t**" << endl;
    	cout << "**\t  " << 4 << "\t\t" << "保存功能\t**" << endl;
    	cout << "**\t  " << 5 << "\t\t" << "退出    \t**" << endl;
    	cout << "******************************************" << endl << endl;
    }
    
    //总的添加函数  可以选择添加学生基础信息还是已有的学生的考勤信息或者未存在的学生的基础信息加上考勤信息
    void addstudent(struct Kaoqin* K)
    {
    	int i;
    	cout << "******************************************" << endl;
    	cout << "**      功能代号\t" << "具体功能\t**" << endl;
    	cout << "**                                      **" << endl;
    	cout << "**\t  " << 1 << "\t\t" << "添加学生记录\t**" << endl;
    	cout << "**\t  " << 2 << "\t\t" << "添加缺课记录\t**" << endl;
    	cout << "******************************************" << endl << endl;
    	cout << "请输入您想要添加的类别:";
    	cin >> i;
    	switch (i)
    	{
    	case 1:
    	{
    		int l;
    		char ID[24];
    		cout << "请输入您所要添加的学生的学号:";
    		cin >> ID;
    		if (K->K_size == 0)
    		{
    			AddStu(K, ID);
    		}
    		else
    		{
    			l = LookID(K, ID);
    			if (l != 10000)
    			{
    				cout << "该学号信息已经存在,请勿重复添加该学生的基础信息!!!!!" << endl;
    				cout << "请按下任意键实现取消添加!!" << endl;
    			}
    			else
    			{
    				AddStu(K, ID);
    			}
    		}
    		break;
    	}
    	case 2:
    	{
    		int l;
    		char ID[24];
    		cout << "请输入您想添加缺课记录的学生的学号:";
    		cin >> ID;
    		//判断结构体是否为空 若为空就不存在寻找是否会出现去寻找是否重复出现学生记录的操作
    		if (K->K_size == 0)
    		{
    			AddStu(K, ID);
    			Addque(K, K->K_size);
    		}
    		else
    		{
    			l = LookID(K, ID);//判断是否学号是否已经存在  若存在就直接跳输入基础信息,只输入考勤信息;否则就需要先输入基本信息  再输入考勤信息
    			if (l == 10000)
    			{
    				AddStu(K, ID);
    				Addque(K, K->K_size - 1);//这里减 1 的原因是 在每一次添加学生的基础信息后就自动给 K->K_size 加了1,以达到假扩容的目的,
    			}                            //以便于在此添加学生信息有空间,然而在这里我们输入的考勤信息是本次添加的学生的,若不减去 1 就会把这个
    			else                        //考勤信息给到下一个学生
    			{
    				Addque(K, l);
    			}
    		}
    		break;
    	}
    	}
    }
    
    
    
    //添加学生基础信息的函数  即添加学生结构体中的信息
    void AddStu(struct Kaoqin* K, char ID[24])
    {
    	int t;
    	if (K->K_size != 0)
    	{
    		t = LookID(K, ID);
    		if (t == 10000)
    		{
    			strcpy(K->stu[K->K_size].S_ID, ID);
    			cout << "请输入您所要新添加的学生的姓名:";
    			cin >> K->stu[K->K_size].S_name;
    			cout << "请输入您所要新添加的学生的性别:";
    			cin >> K->stu[K->K_size].S_sex;
    			cout << "请输入您所要新添加的学生的年龄:";
    			cin >> K->stu[K->K_size].S_age;
    			cout << "请输入您所要新添加的学生的班级信息:";
    			cin >> K->stu[K->K_size].S_class;
    			K->K_size = K->K_size + 1;
    		}
    		else
    		{
    			cout << "该学号信息已经存在,请勿重复添加该学生的基础信息!!!!!" << endl;
    			cout << "是否想要添加该学号学生的缺课信息:1  是   任意键    否";
    			string i;
    			cin >> i;
    			if (i == "1")
    			{
    				Addque(K, t);
    			}
    			else
    			{
    				cout << "请按下任意键实现取消添加!!" << endl;
    				system("pause");
    			}
    		}
    	}
    	else
    	{
    		strcpy(K->stu[K->K_size].S_ID, ID);
    		cout << "请输入您所要新添加的学生的姓名:";
    		cin >> K->stu[K->K_size].S_name;
    		cout << "请输入您所要新添加的学生的性别:";
    		cin >> K->stu[K->K_size].S_sex;
    		cout << "请输入您所要新添加的学生的年龄:";
    		cin >> K->stu[K->K_size].S_age;
    		cout << "请输入您所要新添加的学生的班级信息:";
    		cin >> K->stu[K->K_size].S_class;
    		K->K_size = K->K_size + 1;
    	}
    }
    
    //添加缺课记录函数
    void Addque(struct Kaoqin* K, int i)
    {
    	cout << "请输入您所要新添加的学号的同学所缺课的日期:";
    	cin >> K->que[i].Q_data;
    	cout << "请输入您所要新添加的学号的同学所缺的课是第几节课:";
    	cin >> K->que[i].Q_diclass;
    	cout << "请输入您所要新添加的学号的同学所缺课的课程名称:";
    	cin >> K->que[i].Q_project;
    	cout << "请输入您所要新添加的学号的同学缺课的类型:(迟到、早退、请假、旷课 )   ";
    	cin >> K->que[i].Q_sort;
    }
    //显示函数
    void showkaoqin(struct Kaoqin* K)
    {
    	int i;
    	cout << "\t学号\t姓名\t性别\t年龄\t班级\t缺课日期\t第几节课\t课程名称\t缺课类型\t" << endl;
    	for (i = 0; i < K->K_size; i++)
    	{
    		cout << "\t" << K->stu[i].S_ID << "\t" << K->stu[i].S_name << "\t" << K->stu[i].S_sex << "\t" << K->stu[i].S_age << "\t" << K->stu[i].S_class << "\t" << K->que[i].Q_data << "\t" << K->que[i].Q_diclass << "\t" << K->que[i].Q_project << "\t" << K->que[i].Q_sort << "\t" << endl;
    	}
    }
    //查找函数
    int LookID(struct Kaoqin* K, char ID[24])
    {
    	int i;
    	int t = 10000;
    	for (i = 0; i <= K->K_size; i++)
    	{
    		if (K->stu[i].S_ID == ID)
    		{
    
    			t = i;
    			break;
    		}
    	}
    	return t;
    }
    //保存函数 保存到kaoqin 文件
    void preserve(struct Kaoqin* K)
    {
    	int i;
    	for (i = 0; i < K->K_size; i++)
    	{
    		if (K->que[i].Q_data == "")
    		{
    			strcpy(K->que[i].Q_data, "无");
    			strcpy(K->que[i].Q_diclass, "无");
    			strcpy(K->que[i].Q_project, "无");
    			strcpy(K->que[i].Q_sort, "无");
    		}
    	}
    	ofstream ofs;
    	string number;
    	cout << "请输入您想要保存的文件名(请以 .txt 结尾) " << endl;
    	cin >> filename;
    	ofs.open(filename, ios::out | ios::in | ios::app);
    	cout << "您输入的文件名是否在此之前您是否用过: 0 不是   其余键   是" << endl;
    	cin >> number;
    	//判断文件是否使用过,如果没有使用过就输出表头,没有就不输出,避免重复输出表头
    	if (number == "0")
    	{
    		ofs << "学号\t姓名\t性别\t年龄\t班级\t缺课日期\t第几节课\t课程名称\t缺课类型\t" << endl;
    	}
    	for (i = 0; i < K->K_size; i++)
    	{
    		ofs << K->stu[i].S_ID << "\t" << K->stu[i].S_name << "\t" << K->stu[i].S_sex << "\t" << K->stu[i].S_age << "\t" << K->stu[i].S_class << "\t" << K->que[i].Q_data << "\t" << K->que[i].Q_diclass << "\t" << K->que[i].Q_project << "\t" << K->que[i].Q_sort << "\t" << endl;
    	}
    	ofs.close();
    }
    
    //统计函数  只能根据学号进行统计  因为学号是唯一可以独立代表学生的信息
    void tongji(struct Kaoqin* K, char ID[24])
    {
    	int i;
    	int tong[MAX][4];
    	int chidao = 0;
    	int zaotui = 0;
    	int qingjia = 0;
    	int kuangke = 0;
    	int m[MAX];
    	ofstream ofs;
    	string file;
    	cout << "请输入您想将统计信息的保存的文件夹名称(请以 .txt 结尾)" << endl;
    	cin >> file;
    	cout << endl;
    	ofs.open(file, ios::out | ios::in | ios::app);
    	cout << "您输入的文件名是否在此之前您是否用过:0 不是   其余键   是" << endl;
    	string number;
    	cin >> number;
    	//判断文件是否使用过,如果没有使用过就输出表头,没有就不输出,避免重复输出表头
    	if (number == "0")
        {
            ofs << "学号         \t姓名         \t性别\t年龄\t班级   \t缺课日期\t第几节课\t课程名称\t迟到次数\t早退次数\t请假次数\t旷课次数" << endl;
        }
    
    	cout<<"1   从当前记录中去统计学生的考勤记录   2   从已有文件之中去统计学生的考勤记录 "<<endl;
    	int Q;
    	cin>>Q;
    	cout<<endl<<endl;
    	switch(Q)
    	{
        case 1:
            {
                int k=0;
                int m[MAX];
                //该循环用于查找学号重复的学生  并且存储他们在结构体中的序号
                for (i = 0; i <K->K_size; i++)
                {
                    if (K->stu[i].S_ID==ID)
                    {
                        m[k]=i;//存储序号
                        k = k + 1;//数组扩容
                    }
                }
               for (i = 0; i <K->K_size; i++)
                {
                    if (K->que[m[i]].Q_sort == "迟到")
                    {
                        chidao = chidao + 1;
                        tong[m[i]][0] = chidao;
                        tong[m[i]][1] = tong[m[i-1]][1];
                        tong[m[i]][2] = tong[m[i-1]][2];
                        tong[m[i]][3] = tong[m[i-1]][3];
                    }
                    else if (K->que[i].Q_sort == "早退")
                    {
                        zaotui = zaotui + 1;
                        tong[m[i]][1] = zaotui;
                        tong[m[i]][0] = tong[m[i-1]][0];
                        tong[m[i]][2] = tong[m[i-1]][2];
                        tong[m[i]][3] = tong[m[i-1]][3];
                    }
                    else if (K->que[m[i]].Q_sort == "请假")
                    {
                        qingjia = qingjia + 1;
                        tong[m[i]][2] = tong[m[i]][2];
                        tong[m[i]][0] = tong[m[i]][0];
                        tong[m[i]][1] = tong[m[i]][1];
                        tong[m[i]][3] = tong[m[i]][3];
                    }
                    else if (K->que[i].Q_sort == "旷课")
                    {
                        kuangke = kuangke + 1;
                        tong[m[i]][3] = kuangke;
                        tong[m[i]][2] = tong[m[i]][2];
                        tong[m[i]][0] = tong[m[i]][0];
                        tong[m[i]][1] = tong[m[i]][1];
                    }
                    else
                    {
                        tong[m[i]][3] = tong[m[i-1]][3];
                        tong[m[i]][2] = tong[m[i-1]][2];
                        tong[m[i]][0] = tong[m[i-1]][0];
                        tong[m[i]][1] = tong[m[i-1]][1];
                    }
                }
            ofs << K->stu[m[k-1]].S_ID << "\t" << K->stu[m[k-1]].S_name << "\t" << K->stu[m[k-1]].S_sex << "\t" << K->stu[m[k-1]].S_age << "\t"
                << K->stu[m[k-1]].S_class << "\t" << K->que[m[k-1]].Q_data << "\t" << K->que[m[k-1]].Q_diclass
    			<< "\t" << K->que[m[k-1]].Q_project << "\t" << tong[m[k-1]][0] << "\t" << tong[m[k-1]][1] << "\t" << tong[m[k-1]][2] << "\t" << tong[m[k-1]][3] << endl;
            }
        case 2:
            {
                //读文件中的信息并且统计
               char filename2[24];
               cout << "请输入您想要统计的学生信息的来源文件夹(请以 .txt结尾)" << endl;
               cin >> filename2;
               cout << endl;
               Shuzu A1;
               readfile(filename2,&A1);
               int k=0;
               for (i = 1; i <M; i++)
                {
                    if (strcmp(A1.AA[i].AA1[0],ID)==0)
                    {
                        m[k]=i;
                        k = k + 1;
                    }
                }
            char *Sort[24];
            Sort[0]="迟到";
            Sort[1]="早退";
            Sort[2]="请假";
            Sort[3]="旷课";
            for (i = 0; i < k; i++)
            {
                if (strcmp(Sort[0],A1.AA[m[i]].AA1[8])==0)
                {
                    chidao = chidao + 1;
                    tong[m[i]][0] = chidao;
                    tong[m[i]][1] = tong[m[i-1]][1];
                    tong[m[i]][2] = tong[m[i-1]][2];
                    tong[m[i]][3] = tong[m[i-1]][3];
    			}
    			else if (strcmp(Sort[1],A1.AA[m[i]].AA1[8])==0)
                {
                    zaotui = zaotui + 1;
                    tong[m[i]][1] = zaotui;
                    tong[m[i]][0] = tong[m[i-1]][0];
                    tong[m[i]][2] = tong[m[i-1]][2];
                    tong[m[i]][3] = tong[m[i-1]][3];
                }
                else if (strcmp(Sort[2],A1.AA[m[i]].AA1[8])==0)
                {
                    qingjia = qingjia + 1;
                    tong[m[i]][2] = tong[m[i-1]][2];
                    tong[m[i]][0] = tong[m[i-1]][0];
                    tong[m[i]][1] = tong[m[i-1]][1];
                    tong[m[i]][3] = tong[m[i]][3];
                }
                else if (strcmp(Sort[3],A1.AA[m[i]].AA1[8])==0)
                {
                    kuangke = kuangke + 1;
                    tong[m[i]][3] = kuangke;
                    tong[m[i]][2] = tong[m[i-1]][2];
                    tong[m[i]][0] = tong[m[i-1]][0];
                    tong[m[i]][1] = tong[m[i-1]][1];
                }
                else
                {
                    tong[m[i]][3] = tong[m[i-1]][3];
                    tong[m[i]][2] = tong[m[i-1]][2];
                    tong[m[i]][0] = tong[m[i-1]][0];
                    tong[m[i]][1] = tong[m[i-1]][1];
                }
            }
    	//只输出最终结果
        ofs << A1.AA[m[k-1]].AA1[0] << "\t" <<A1.AA[m[k-1]].AA1[1] << "\t" << A1.AA[m[k-1]].AA1[2] << "\t" << A1.AA[m[k-1]].AA1[3]<< "\t"
            << A1.AA[m[k-1]].AA1[4] << "\t" <<A1.AA[m[k-1]].AA1[5]<< "\t" << A1.AA[m[k-1]].AA1[6]
            << "\t" <<A1.AA[m[k-1]].AA1[7]<< "\t" << tong[m[k-1]][0] << "\t" << tong[m[k-1]][1] << "\t" << tong[m[k-1]][2] << "\t" << tong[m[k-1]][3] << endl;
        }
    	ofs.close();
    	}
    }
    
    
    //读入存储考勤信息的文件内的信息
    void readfile(char* filename, struct Shuzu *A1)
    {
    	ifstream filename1(filename, ios::in);
    	if (!filename1)
    	{
    		cout << "文件打开出错!!!" << endl;
    		exit(1);
    	}
    	M=Readfile(filename);
    	for (int i = 0; i <M; i++)
    	{
    		for (int j = 0; j < 9; j++)
    		{
    			filename1 >>A1->AA[i].AA1[j];
    		}
    	}
    	filename1.close();
    }
    
    
    //计算文件的行数(每一行数据个数一定)
    int Readfile(char *filename)
    {
        char *buf=(char*)malloc(24);
        ifstream filename1(filename, ios::in);
    	if (!filename1)
    	{
    		cout << "文件打开出错!!!" << endl;
    		exit(1);
    	}
    	FILE *fp;
    	fp=fopen(filename,"rb");
    	if(fp==NULL)
        {
    
            cout<<"文件打开失败"<<endl;
        }
    	int N=0;
    	float K;
    	while(!feof(fp))
        {
            fscanf(fp,"%s",buf+(N++));
        }
        fclose(fp);
        K=N/9;//该语句表示文件的总的行数为K行   总的数据个数为N个(带了表头),每一行的数据个数为9个
    	filename1.close();
    	return K;
    }
    
    

  • 7
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仔仔军

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值