题目中的各个功能都是相对独立的,所以我将各项功能以 带 编号 的菜单形式组织在屏幕上,
用户通过 输入 编号 执行相应的功能。显示菜单的代码处于一个循环之中,当执行完一个
子功能后,就又回到循环,显示主菜单,直到用户选择 退出 菜单。
这种操作方式比其它机制(如:主程序 + 程序参数)更简捷,不必每次用不同的参数重新运行程序,
以实现相应的功能。
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 ....
#include "stdio.h" #define CMD_START printf("\n\n######### Start a command #########\n"); typedef struct tagStudent int ShowMenu(); /* 在屏幕上打印 主菜单 的函数,它的返回值为 所选 菜单的 项目编号 */ /* 题目中要求的函数 */ int quit; /* 一个全局变量,在下面的 main() 函数中,用来决定何时退出主循环 */ main() quit = 0; /* 初始化 为 不退出 */ /* 这是程序的主循环,每次都将 主菜单打印出来, cmd = ShowMenu(); /* 显示 主菜单,并返回用户所选择的 菜单项 的 编号 */ CMD_START /* 在屏幕上打印一行分隔符,告诉用户这是一个子功能的开始 */ switch( cmd ) /* 用多项分支 根据 用户的选择 调用 相应的函数 */ break; default: CMD_END /* 打印一行分隔符,告诉用户 他所选择的菜单的功能已经执行完毕 */ if (quit != 1) /* 检查用户是否 要求 退出 */ } } int ShowMenu() int cmd = 0; /* 保存用户的选择 */ /* 定义 程序所支持的菜单项目 */ /* 在屏幕上打印 主菜单 */ printf(Menu_SeeData); printf("\n##############################################"); printf("\n\n Input the index of your choice : "); scanf("%d" , &cmd); /* 接受用户 选择 */ printf("\n"); return cmd; /* 返回用户的输入,交给主循环处理 */ } void Print() /* 打印 数据文件的 记录内容 */ FILE* fp = NULL; /* 文件指针 */ fp = fopen(DATA_FILE , "rb"); /* 以 二进制读 方式 打开数据文件 */ while(ReadData(fp , &rec)) /* ReadData() 函数出错或到文件末尾时返回 0,可以做循环条件 */ i++; /* 计数器 加一 */ fclose(fp); /* 关闭文件 */ } void Add() /* 添加记录 */ Student rec; Input_Rec( &rec ); /* 让用户输入新记录的各项内容 */ fp = fopen(DATA_FILE ,"ab"); /* 以 添加 方式打开数据文件 */ if( WriteData(fp, &rec) == 1) /* 将 新记录 写入文件,并检查 是否正确写入*/ fclose(fp); } void Delete() /* 删除记录 */ Student rec; int del_count; /* 实际 删除的 记录数目 */ printf("\n Please type the ID of the record you want me to delete ."); fpr = fopen(DATA_FILE ,"rb"); /* 从 原来的记录文件中读取数据,跳过将要删除的记录 */ fpw = fopen(TEMP_FILE,"wb"); /* 打开一个 临时文件 保存不删除的记录 */ fclose(fpr); strcpy(cmd , "del "); /* 构造命令串,用 system() 函数执行 */ system(cmd); rename(TEMP_FILE,DATA_FILE); /* 直接调用 C 语言的改名函数将临时文件改名为数据文件的名字*/ printf("\n I have delete\t%d\trecord .\n" ,del_count); } void Statistics() /* 统计分析函数 */ Student stu_math_high,stu_english_high; /* 各科 最高分的学生记录副本 */ Student stu_math_low,stu_english_low; /* 各科最低的学生记录副本 */ FILE* fp; int count; /* 一个计数器,用于判断是否第一次读取数据 */ count = sum = sum_high = sum_low = i50 = i60 = i60 = i70 =i80 = i90 = 0; while(ReadData(fp , &rec)) /* 读取数据 */ sum = rec.Math + rec.English + rec.Compute + rec.PE+ rec.Philosophy; /* 求和 */ /* average */ /*highest and loeest*/ if(sum < sum_low) /* subject highest and low */ CopyRec(&stu_math_low,&rec); } if(rec.English > stu_english_high.English) if(rec.Compute > stu_compute_high.Compute) if(rec.Philosophy > stu_philosophy_high.Philosophy) if(rec.PE > stu_PE_high.PE) /* low */ if(rec.English < stu_english_low.English) if(rec.Compute < stu_compute_low.Compute) if(rec.Philosophy < stu_philosophy_low.Philosophy) if(rec.PE < stu_PE_low.PE) } if(count < 1) getch(); /*highest and loeest*/ /* 输出总分最高的学生的信息 */ getch(); /* subject highest and low */ getch(); /* 暂停 ,按任意键继续 */ printf(" The Highest English :\n"); getch(); printf(" The Highest Compute :\n"); getch(); printf(" The Highest Philosophy :\n"); getch(); printf(" The Highest PE :\n"); } } |
void Find(int isFind_From_ID) /* 查找函数 */ char buf[30]; /* 接受用户输入的条件的缓冲区 */ find_count = 0; fp = fopen(DATA_FILE ,"rb"); switch(isFind_From_ID) printf("\n Please Input the ID : "); while(ReadData(fp , &rec)) /* 读取数据 */ case 6: /*Name ,按 姓名 查找*/ while(ReadData(fp , &rec)) break; default: } fclose(fp); }
r = fread(Dest_Rec ,sizeof(Student) ,1 ,fp); return 1; } int WriteData(FILE* fp, Student* Src_Rec) /* 写入数据记录 */ r = fwrite(Src_Rec , sizeof(Student) , 1, fp); return 1; } void Output_Rec( Student* stu) /* 在屏幕上输出 一个学生的信息 */ printf(" Name : %s", stu->Name); 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("\n"); void Input_Rec( Student* stu) /* 让用户输入 一个学生的各项信息 */ if(stu == NULL) printf("\n Name = "); /* 下面这段代码实现只能输入 F ,f ,M ,m 的功能 */ if(stu->Sex == 'F' || stu->Sex == 'f' || stu->Sex == 'M' || stu->Sex == 'm') /* 下面 给出提示,让用户输入结构体的各项内容 */ printf("\n Class = "); printf("\n Math = "); printf("\n English = "); printf("\n Compute = "); printf("\n Philosophy = "); printf("\n PE = "); printf("\n"); } /* 因为结构体不能直接用 等号(=)赋值,写一个赋值函数 */ void Find(int isFind_From_ID) /* 查找函数 */ char buf[30]; /* 接受用户输入的条件的缓冲区 */ find_count = 0; fp = fopen(DATA_FILE ,"rb"); switch(isFind_From_ID) printf("\n Please Input the ID : "); while(ReadData(fp , &rec)) /* 读取数据 */ case 6: /*Name ,按 姓名 查找*/ while(ReadData(fp , &rec)) break; default: } fclose(fp); }
r = fread(Dest_Rec ,sizeof(Student) ,1 ,fp); return 1; } int WriteData(FILE* fp, Student* Src_Rec) /* 写入数据记录 */ r = fwrite(Src_Rec , sizeof(Student) , 1, fp); return 1; } void Output_Rec( Student* stu) /* 在屏幕上输出 一个学生的信息 */ printf(" Name : %s", stu->Name); 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("\n"); void Input_Rec( Student* stu) /* 让用户输入 一个学生的各项信息 */ if(stu == NULL) printf("\n Name = "); /* 下面这段代码实现只能输入 F ,f ,M ,m 的功能 */ if(stu->Sex == 'F' || stu->Sex == 'f' || stu->Sex == 'M' || stu->Sex == 'm') /* 下面 给出提示,让用户输入结构体的各项内容 */ printf("\n Class = "); printf("\n Math = "); printf("\n English = "); printf("\n Compute = "); printf("\n Philosophy = "); printf("\n PE = "); printf("\n"); } /* 因为结构体不能直接用 等号(=)赋值,写一个赋值函数 */ void Find(int isFind_From_ID) /* 查找函数 */ char buf[30]; /* 接受用户输入的条件的缓冲区 */ find_count = 0; fp = fopen(DATA_FILE ,"rb"); switch(isFind_From_ID) printf("\n Please Input the ID : "); while(ReadData(fp , &rec)) /* 读取数据 */ case 6: /*Name ,按 姓名 查找*/ while(ReadData(fp , &rec)) break; default: } fclose(fp); }
r = fread(Dest_Rec ,sizeof(Student) ,1 ,fp); return 1; } int WriteData(FILE* fp, Student* Src_Rec) /* 写入数据记录 */ r = fwrite(Src_Rec , sizeof(Student) , 1, fp); return 1; } void Output_Rec( Student* stu) /* 在屏幕上输出 一个学生的信息 */ printf(" Name : %s", stu->Name); 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("\n"); void Input_Rec( Student* stu) /* 让用户输入 一个学生的各项信息 */ if(stu == NULL) printf("\n Name = "); /* 下面这段代码实现只能输入 F ,f ,M ,m 的功能 */ if(stu->Sex == 'F' || stu->Sex == 'f' || stu->Sex == 'M' || stu->Sex == 'm') /* 下面 给出提示,让用户输入结构体的各项内容 */ printf("\n Class = "); printf("\n Math = "); printf("\n English = "); printf("\n Compute = "); printf("\n Philosophy = "); printf("\n PE = "); printf("\n"); } /* 因为结构体不能直接用 等号(=)赋值,写一个赋值函数 */ /* 题目分析 及 算法设计 : 题目中的各个功能都是相对独立的,所以我将各项功能以 带 编号 的菜单形式组织在屏幕上, 这种操作方式比其它机制(如:主程序 + 程序参数)更简捷,不必每次用不同的参数重新运行程序, 2. 添加记录 的实现: 3. 删除记录 的实现: 4. 统计功能 的实现: 5. 查找功能 的实现: 有关各个变量的作用都已经在代码中表明,非常详细。 |
欢迎访问最专业的网吧论坛,无盘论坛,网吧经营,网咖管理,网吧专业论坛
https://bbs.txwb.com
关注天下网吧微信/下载天下网吧APP/天下网吧小程序,一起来超精彩
|
本文来源:vczx 作者:佚名