原帖及评论:http://bbs.bccn.net/thread-83340-1-1.html 替同学写了作业,如下,我同学说看不懂啊 。。。 就添加了很详细的注释,大家有兴趣的就看看吧 。。。 ==================================================== 代码在第二个,三个帖子中贴出来了,太长了,一个帖子不够用
==================================================== 题目分析 及 算法设计 : 题目中的各个功能都是相对独立的,所以我将各项功能以 带 编号 的菜单形式组织在屏幕上, 用户通过 输入 编号 执行相应的功能。显示菜单的代码处于一个循环之中,当执行完一个 子功能后,就又回到循环,显示主菜单,直到用户选择 退出 菜单。 这种操作方式比其它机制(如:主程序 + 程序参数)更简捷,不必每次用不同的参数重新运行程序, 以实现相应的功能。 1. 查看文件记录内容 的实现: 用 循环 读取文件内容,然后显示在屏幕上。 因为 我们的数据是以结构体的形式存放在文件中的,所以 代码中用了块读取和块写入函数。 在 循环中设置计数器来统计记录的个数。 2. 添加记录 的实现: 让用户根据屏幕提示输入数据,完成对学生信息结构体各项的赋值,待取得足够数据后, 将数据文件以“追加”方式打开,执行块写入,将整个结构体写入文件。 3. 删除记录 的实现: 学号(ID)一般不会重复,所以我在程序中让用户输入想要删除的记录的学号(ID), 然后在文件中查找,如果不是用户想要删除的记录(即ID不同),就保存在一个临时的文件中, 这样,就将想要删除的记录与其它记录分离开了,最后,删除原来的数据文件,将临时文件的 名字改为 原来数据文件的名字。 4. 统计功能 的实现: 统计功能模块分为三个小模块:平均分的分数段统计,总分的最高和最低分统计, 各科的最高和最低分统计。但我并不想分别来写,因为它们都要对所有记录进行扫描, 而它们又互不干扰,所以我把它们组织在一个循环中,各自都有自己的计算代码和变量, 所以这个 函数 中的局部变量 很多。 5. 查找功能 的实现: 题目要求两种查找方式:按 学号(ID) , 按 姓名(Name)。 两者是独立的,所以我用了一个参数 isFind_From_ID 来表明是哪种查找方式,进而在在程序 内部由一个 switch() 选择分支转向不同的代码段去执行。 具体的查找就是比较相应的项目是否与用户输入的一样,若一样就输出到屏幕。 有关各个变量的作用都已经在代码中表明,非常详细。 =================================================================================== 运行效果如下(在dos环境中运行): ############ Main Menu ############### ############################################## 1 . View the Records in the data file 2 . Add New Record 3 . Delete an old Record 4 . Make a Statistics 5 . Find a Record from the ID 6 . Find a Record from the Name 7 . Quit ############################################## Input the index of your choice : 1 ######### Start a command ######### Name : wewewew Sex : Female ID : 232323 Class : sasas Math = -858993460 English = -858993460 Compute = -858993460 Philosophy = -858993460 PE = -858993460 ------------------------------------------ Name : ww Sex : Female ID : 2121 Class : 12 Math = 123 English = 123 Compute = 123 Philosophy = 123 PE = 123 ------------------------------------------ The current data file have 2 record . ######### End a command ######### Press any key to Return Main Menu .... void Find(int isFind_From_ID) /* 查找函数 */ { char buf[30]; /* 接受用户输入的条件的缓冲区 */ Student rec; int find_count; /* 查找到的记录数目 */ FILE* fp; find_count = 0; fp = fopen(DATA_FILE ,"rb"); if( fp == NULL) { printf("/n Can not open the data file to search .../n"); return; } switch(isFind_From_ID) { case 5: /*ID,按 学号查找*/ printf("/n Please Input the ID : "); scanf("%s",buf); /* 提示用户输入 */ while(ReadData(fp , &rec)) /* 读取数据 */ { if(strcmp(rec.ID , buf) == 0) /* 比较 */ { find_count++; Output_Rec(&rec); /* 输出符合条件的记录 */ printf(" ------------------------------------------/n"); } } break; case 6: /*Name ,按 姓名 查找*/
printf("/n Please Input the Name : "); scanf("%s",buf); while(ReadData(fp , &rec)) { if(strcmp(rec.Name , buf) == 0) { find_count++; Output_Rec(&rec); printf(" ------------------------------------------/n"); } } break; default: printf(" /nPlease type right index .../n"); /*处理isFind_From_ID既不是5也不是6的情况*/ }
if(find_count >0) /* 输出找到的记录数目 */ { printf("/n Have find out/t%d/trecord/n" ,find_count); } else { printf("/n I'm very sorry ./n I failed to find out the one you want ./n"); printf("/n I suggest that you change some other key words ./n"); } fclose(fp); } int ReadData(FILE* fp, Student* Dest_Rec) /* 读取数据记录 */ { int r; if(( fp == NULL ) || ( Dest_Rec == NULL)) return 0; /* ERROR */
r = fread(Dest_Rec ,sizeof(Student) ,1 ,fp); if(r != 1) return 0; return 1; } int WriteData(FILE* fp, Student* Src_Rec) /* 写入数据记录 */ { int r; if((fp == NULL) || (Src_Rec == NULL)) return 0; /* ERROR */ r = fwrite(Src_Rec , sizeof(Student) , 1, fp); if(r != 1) return 0; return 1; } void Output_Rec( Student* stu) /* 在屏幕上输出 一个学生的信息 */ { printf("/n"); printf(" Name : %s", stu->Name); printf("/t/tSex : "); if( stu->Sex == 'M' || stu->Sex == 'm' ) printf("Male"); else printf("Female"); printf("/n ID : %s/t/tClass : %s/n",stu->ID ,stu->Class); printf("Math = %d/tEnglish = %d/tCompute = %d/n" ,stu->Math ,stu->English, stu->Compute); printf("Philosophy = %d/t/tPE = %d/n", stu->Philosophy ,stu->PE); printf("/n"); } void Input_Rec( Student* stu) /* 让用户输入 一个学生的各项信息 */ { if(stu == NULL) return; printf("/n Name = "); scanf("%s",stu->Name); /* 下面这段代码实现只能输入 F ,f ,M ,m 的功能 */ printf("/tSex = (F|M) "); while(1) { stu->Sex = getch(); /* 无回显输入 */ if(stu->Sex == 'F' || stu->Sex == 'f' || stu->Sex == 'M' || stu->Sex == 'm') { printf("%c",stu->Sex); /* 将用户输入的字符输出,模拟正常输入数据时的回显 */ break; } } /* 下面 给出提示,让用户输入结构体的各项内容 */ printf("/n ID = "); scanf("%s" , stu->ID); printf("/n Class = "); scanf("%s" , stu->Class); printf("/n Math = "); scanf("%d", &(stu->Math)); printf("/n English = "); scanf("%d" ,&(stu->English)); printf("/n Compute = "); scanf("%d" , &(stu->Compute)); printf("/n Philosophy = "); scanf("%d" , &(stu->Philosophy)); printf("/n PE = "); scanf("%d" , &(stu->PE)); printf("/n"); } /* 因为结构体不能直接用 等号(=)赋值,写一个赋值函数 */ void CopyRec(Student* dest_stu, Student* src_stu) { /* 复制 源记录 的各项到 目标记录*/ strcpy(dest_stu->Name ,src_stu->Name); strcpy(dest_stu->ID ,src_stu->ID); strcpy(dest_stu->Class ,src_stu->Class); dest_stu->Sex = src_stu->Sex; dest_stu->Math = src_stu->Math; dest_stu->English = src_stu->English; dest_stu->Compute = src_stu->Compute; dest_stu->Philosophy = src_stu->Philosophy; dest_stu->PE = src_stu->PE; } void Find(int isFind_From_ID) /* 查找函数 */ { char buf[30]; /* 接受用户输入的条件的缓冲区 */ Student rec; int find_count; /* 查找到的记录数目 */ FILE* fp; find_count = 0; fp = fopen(DATA_FILE ,"rb"); if( fp == NULL) { printf("/n Can not open the data file to search .../n"); return; } switch(isFind_From_ID) { case 5: /*ID,按 学号查找*/ printf("/n Please Input the ID : "); scanf("%s",buf); /* 提示用户输入 */ while(ReadData(fp , &rec)) /* 读取数据 */ { if(strcmp(rec.ID , buf) == 0) /* 比较 */ { find_count++; Output_Rec(&rec); /* 输出符合条件的记录 */ printf(" ------------------------------------------/n"); } } break; case 6: /*Name ,按 姓名 查找*/
printf("/n Please Input the Name : "); scanf("%s",buf); while(ReadData(fp , &rec)) { if(strcmp(rec.Name , buf) == 0) { find_count++; Output_Rec(&rec); printf(" ------------------------------------------/n"); } } break; default: printf(" /nPlease type right index .../n"); /*处理isFind_From_ID既不是5也不是6的情况*/ }
if(find_count >0) /* 输出找到的记录数目 */ { printf("/n Have find out/t%d/trecord/n" ,find_count); } else { printf("/n I'm very sorry ./n I failed to find out the one you want ./n"); printf("/n I suggest that you change some other key words ./n"); } fclose(fp); } int ReadData(FILE* fp, Student* Dest_Rec) /* 读取数据记录 */ { int r; if(( fp == NULL ) || ( Dest_Rec == NULL)) return 0; /* ERROR */
r = fread(Dest_Rec ,sizeof(Student) ,1 ,fp); if(r != 1) return 0; return 1; } int WriteData(FILE* fp, Student* Src_Rec) /* 写入数据记录 */ { int r; if((fp == NULL) || (Src_Rec == NULL)) return 0; /* ERROR */ r = fwrite(Src_Rec , sizeof(Student) , 1, fp); if(r != 1) return 0; return 1; } void Output_Rec( Student* stu) /* 在屏幕上输出 一个学生的信息 */ { printf("/n"); printf(" Name : %s", stu->Name); printf("/t/tSex : "); if( stu->Sex == 'M' || stu->Sex == 'm' ) printf("Male"); else printf("Female"); printf("/n ID : %s/t/tClass : %s/n",stu->ID ,stu->Class); printf("Math = %d/tEnglish = %d/tCompute = %d/n" ,stu->Math ,stu->English, stu->Compute); printf("Philosophy = %d/t/tPE = %d/n", stu->Philosophy ,stu->PE); printf("/n"); } void Input_Rec( Student* stu) /* 让用户输入 一个学生的各项信息 */ { if(stu == NULL) return; printf("/n Name = "); scanf("%s",stu->Name); /* 下面这段代码实现只能输入 F ,f ,M ,m 的功能 */ printf("/tSex = (F|M) "); while(1) { stu->Sex = getch(); /* 无回显输入 */ if(stu->Sex == 'F' || stu->Sex == 'f' || stu->Sex == 'M' || stu->Sex == 'm') { printf("%c",stu->Sex); /* 将用户输入的字符输出,模拟正常输入数据时的回显 */ break; } } /* 下面 给出提示,让用户输入结构体的各项内容 */ printf("/n ID = "); scanf("%s" , stu->ID); printf("/n Class = "); scanf("%s" , stu->Class); printf("/n Math = "); scanf("%d", &(stu->Math)); printf("/n English = "); scanf("%d" ,&(stu->English)); printf("/n Compute = "); scanf("%d" , &(stu->Compute)); printf("/n Philosophy = "); scanf("%d" , &(stu->Philosophy)); printf("/n PE = "); scanf("%d" , &(stu->PE)); printf("/n"); } /* 因为结构体不能直接用 等号(=)赋值,写一个赋值函数 */ void CopyRec(Student* dest_stu, Student* src_stu) { /* 复制 源记录 的各项到 目标记录*/ strcpy(dest_stu->Name ,src_stu->Name); strcpy(dest_stu->ID ,src_stu->ID); strcpy(dest_stu->Class ,src_stu->Class); dest_stu->Sex = src_stu->Sex; dest_stu->Math = src_stu->Math; dest_stu->English = src_stu->English; dest_stu->Compute = src_stu->Compute; dest_stu->Philosophy = src_stu->Philosophy; dest_stu->PE = src_stu->PE; } void Find(int isFind_From_ID) /* 查找函数 */ { char buf[30]; /* 接受用户输入的条件的缓冲区 */ Student rec; int find_count; /* 查找到的记录数目 */ FILE* fp; find_count = 0; fp = fopen(DATA_FILE ,"rb"); if( fp == NULL) { printf("/n Can not open the data file to search .../n"); return; } switch(isFind_From_ID) { case 5: /*ID,按 学号查找*/ printf("/n Please Input the ID : "); scanf("%s",buf); /* 提示用户输入 */ while(ReadData(fp , &rec)) /* 读取数据 */ { if(strcmp(rec.ID , buf) == 0) /* 比较 */ { find_count++; Output_Rec(&rec); /* 输出符合条件的记录 */ printf(" ------------------------------------------/n"); } } break; case 6: /*Name ,按 姓名 查找*/
printf("/n Please Input the Name : "); scanf("%s",buf); while(ReadData(fp , &rec)) { if(strcmp(rec.Name , buf) == 0) { find_count++; Output_Rec(&rec); printf(" ------------------------------------------/n"); } } break; default: printf(" /nPlease type right index .../n"); /*处理isFind_From_ID既不是5也不是6的情况*/ }
if(find_count >0) /* 输出找到的记录数目 */ { printf("/n Have find out/t%d/trecord/n" ,find_count); } else { printf("/n I'm very sorry ./n I failed to find out the one you want ./n"); printf("/n I suggest that you change some other key words ./n"); } fclose(fp); } int ReadData(FILE* fp, Student* Dest_Rec) /* 读取数据记录 */ { int r; if(( fp == NULL ) || ( Dest_Rec == NULL)) return 0; /* ERROR */
r = fread(Dest_Rec ,sizeof(Student) ,1 ,fp); if(r != 1) return 0; return 1; } int WriteData(FILE* fp, Student* Src_Rec) /* 写入数据记录 */ { int r; if((fp == NULL) || (Src_Rec == NULL)) return 0; /* ERROR */ r = fwrite(Src_Rec , sizeof(Student) , 1, fp); if(r != 1) return 0; return 1; } void Output_Rec( Student* stu) /* 在屏幕上输出 一个学生的信息 */ { printf("/n"); printf(" Name : %s", stu->Name); printf("/t/tSex : "); if( stu->Sex == 'M' || stu->Sex == 'm' ) printf("Male"); else printf("Female"); printf("/n ID : %s/t/tClass : %s/n",stu->ID ,stu->Class); printf("Math = %d/tEnglish = %d/tCompute = %d/n" ,stu->Math ,stu->English, stu->Compute); printf("Philosophy = %d/t/tPE = %d/n", stu->Philosophy ,stu->PE); printf("/n"); } void Input_Rec( Student* stu) /* 让用户输入 一个学生的各项信息 */ { if(stu == NULL) return; printf("/n Name = "); scanf("%s",stu->Name); /* 下面这段代码实现只能输入 F ,f ,M ,m 的功能 */ printf("/tSex = (F|M) "); while(1) { stu->Sex = getch(); /* 无回显输入 */ if(stu->Sex == 'F' || stu->Sex == 'f' || stu->Sex == 'M' || stu->Sex == 'm') { printf("%c",stu->Sex); /* 将用户输入的字符输出,模拟正常输入数据时的回显 */ break; } } /* 下面 给出提示,让用户输入结构体的各项内容 */ printf("/n ID = "); scanf("%s" , stu->ID); printf("/n Class = "); scanf("%s" , stu->Class); printf("/n Math = "); scanf("%d", &(stu->Math)); printf("/n English = "); scanf("%d" ,&(stu->English)); printf("/n Compute = "); scanf("%d" , &(stu->Compute)); printf("/n Philosophy = "); scanf("%d" , &(stu->Philosophy)); printf("/n PE = "); scanf("%d" , &(stu->PE)); printf("/n"); } /* 因为结构体不能直接用 等号(=)赋值,写一个赋值函数 */ void CopyRec(Student* dest_stu, Student* src_stu) { /* 复制 源记录 的各项到 目标记录*/ strcpy(dest_stu->Name ,src_stu->Name); strcpy(dest_stu->ID ,src_stu->ID); strcpy(dest_stu->Class ,src_stu->Class); dest_stu->Sex = src_stu->Sex; dest_stu->Math = src_stu->Math; dest_stu->English = src_stu->English; dest_stu->Compute = src_stu->Compute; dest_stu->Philosophy = src_stu->Philosophy; dest_stu->PE = src_stu->PE; } /* 题目分析 及 算法设计 : 题目中的各个功能都是相对独立的,所以我将各项功能以 带 编号 的菜单形式组织在屏幕上, 用户通过 输入 编号 执行相应的功能。显示菜单的代码处于一个循环之中,当执行完一个 子功能后,就又回到循环,显示主菜单,直到用户选择 退出 菜单。 这种操作方式比其它机制(如:主程序 + 程序参数)更简捷,不必每次用不同的参数重新运行程序, 以实现相应的功能。 1. 查看文件记录内容 的实现: 用 循环 读取文件内容,然后显示在屏幕上。 因为 我们的数据是以结构体的形式存放在文件中的,所以 代码中用了块读取和块写入函数。 在 循环中设置计数器来统计记录的个数。 2. 添加记录 的实现: 让用户根据屏幕提示输入数据,完成对学生信息结构体各项的赋值,待取得足够数据后, 将数据文件以“追加”方式打开,执行块写入,将整个结构体写入文件。 3. 删除记录 的实现: 学号(ID)一般不会重复,所以我在程序中让用户输入想要删除的记录的学号(ID), 然后在文件中查找,如果不是用户想要删除的记录(即ID不同),就保存在一个临时的文件中, 这样,就将想要删除的记录与其它记录分离开了,最后,删除原来的数据文件,将临时文件的 名字改为 原来数据文件的名字。 4. 统计功能 的实现: 统计功能模块分为三个小模块:平均分的分数段统计,总分的最高和最低分统计, 各科的最高和最低分统计。但我并不想分别来写,因为它们都要对所有记录进行扫描, 而它们又互不干扰,所以我把它们组织在一个循环中,各自都有自己的计算代码和变量, 所以这个 函数 中的局部变量 很多。 5. 查找功能 的实现: 题目要求两种查找方式:按 学号(ID) , 按 姓名(Name)。 两者是独立的,所以我用了一个参数 isFind_From_ID 来表明是哪种查找方式,进而在在程序 内部由一个 switch() 选择分支转向不同的代码段去执行。 具体的查找就是比较相应的项目是否与用户输入的一样,若一样就输出到屏幕。 有关各个变量的作用都已经在代码中表明,非常详细。 */ |