实训报告
题 目: 学生成绩管理系统 院 系: 信息科技学院
专 业: 计算机科学与技术 姓 名:
学 号:
指导教师: 吕元长
日 期: 20xx年9月15日
桂林电子科技大学信息科技学院
目 录
一、课程设计目的 ................................................................................................................... 4
二、课程设计题目 ................................................................................................................... 4
三、课程报告设计内容 ........................................................................................................... 4
3.1 需求分析 .................................................................................................................... 4
3.2 概要设计 .................................................................................................................... 4
3.2.1 部分功能叙述 ......................................................................................................... 4
3.3 框架设计 .................................................................................................................... 5
3.4 详细设计 .................................................................................................................... 6
3.4.1 通讯录信息结构体 ................................................................................................. 6
3.4.2主控main()函数执行流程 ...................................................................................... 6
3.4.3 输出记录模块 ......................................................................................................... 7
3.4.4 查询记录模块 ......................................................................................................... 7
3.4.5 更新记录模块 ......................................................................................................... 7
3.4.5.1 添加模块 .............................................................................................................. 7
3.4.5.2 修改模块 .............................................................................................................. 7
3.4.5.3 删除模块 .............................................................................................................. 7
3.4.5.4 格式化通讯录 ...................................................................................................... 7
3.4.5.5 密码模块 .............................................................................................................. 8
3.4.5.6 导出模块 .............................................................................................................. 8
3.4.5.6 重置模块 .............................................................................................................. 8
3.4.6 关于模块 ................................................................................................................. 8
3.4.7函数功能描述 .......................................................................................................... 8
3.5系统实现 ..................................................................................................................... 9
3.5.1编码 .......................................................................................................................... 9
3.5.1.1 程序预处理 .......................................................................................................... 9
3.5.1.2 主函数main() ...................................................................................................... 9
3.5.1.3表格形式显示记录 ............................................................................................. 10
3.5.1.4 查询记录 ............................................................................................................ 11
3.5.1.5增加记录 ............................................................................................................. 15
3.5.1.6 删除记录 ............................................................................................................ 16
3.5.1.7 修改记录 ............................................................................................................ 18
3.5.1.8 密码模块 ............................................................................................................ 19
3.5.1.8.1初始化密码 ...................................................................................................... 19
3.5.1.8.2 输入密码 ......................................................................................................... 21
3.5.1.8.3 修改密码 ......................................................................................................... 22
3.5.1.9 导出功能 ............................................................................................................ 24
3.5.1.9 重置功能 ............................................................................................................ 24
3.5.1.10 后台菜单 .......................................................................................................... 27
3.5.1.11 界面模块 .......................................................................................................... 27
3.5.2测试与调试 ............................................................................................................ 33
3.5.2.1概述 ..................................................................................................................... 33
3.5.2.2程序测试 ............................................................................................................. 34
四、系统维护 ......................................................................................................................... 34
五、归纳总结 ......................................................................................................................... 34
5.1 开发经验 .............................................................................................................. 34
5.2 实训中遇到的问题及解决方法 .......................................................................... 34
5.3 设计中尚存的不足之处 ...................................................................................... 34
5.4 感想和心得体会 .................................................................................................. 35
六、参考资料 ......................................................................................................................... 35
一、 课程设计目的
本题目设计目的是训练学生的基本编程能力,了解管理信息系统的开发流程,熟悉C语言的文件、的各种基本操作。本程序中涉及结构体、、文件等方面的知识。通过本程序的训练,使学生能对C语言的文件操作有一个更深刻的了解,掌握利用文件存储结构实现对通讯录管理的原理,为进一步开发出高质量的管理信息系统打下坚实的基础。
二、 课程设计题目
题目:通讯录管理系统
描述:使用C语言程序对通讯录信息进行管理,方便信息操作
三、 课程报告设计内容
3.1 需求分析
“通讯录管理系统”主要是实现对姓名以及电话的管理,至于管理主要涉及对通讯录信息的添加,查找,删除,修改,保存以及显示通讯录信息等。在实现基本功能的基础上做到界面美观,清晰,操作简便等。
3.2 概要设计
采用模块化的程序设计方法,即将较大的任务按照一定的原则分为一个个较小的任务,然后分别设计各个小任务。需要注意的是划分出来的模块应该相对独立但又相关,且容易理解。可以用模块化层次结构图(即模块图)来分析其任务的划分,一般从上到下进行,最上面一层是主模块,下面各层是其上一层模块的逐步细化描述。
3.2.1 部分功能叙述
输入记录模块。为记录信息申请临时空间,从键盘中录入姓名信息和号码信息,再用文件追加的方法,直接保存在文件里面。
查询记录模块。完成在文件中查找满足相关条件的通讯录记录。在此通讯录管理系统中,用户可以按照全名查找、模糊查找、号码查找进行查找。声明一个布尔变量且赋初值为0,若找到该通讯录的记录,则改变布尔变量的值。否则,并打印出未找到该学生记录的提示信息。
更新记录模块。输入密码进入此模块,完成对通讯录的维护。在此通讯录管理系统中,它实现了对通讯录记录的修改、删除、插入、导出、格式化。还实现了对通讯录系统修改密码和恢复初始化设置的功能,并将修改后的数据存入源数据文件。
输出记录模块。实现将记录信息以表格的形式在屏幕上打印出来。
3.3 框架设计
3.4 详细设计
3.4.1 通讯录信息结构体
typedef struct friends
{
char name[10]; //姓名
char phone[15]; //号码
}friends;
结构体friends将用于临时存储学生的基本信息。为了简化程序,只取了2个信息。
3.4.2主控main()函数执行流程
本通讯录管理系统执行主流程如图3.4.2所示。它先以只读的方式打开密码存储文件,此文件默认为“password.dat”,若该文件不存在,则新建此文件。进入欢迎界面。再以只读的方式打开信息存储文件,此文件默认为“data.dat”,若该文件不存在,则新建此文件。然后执行显示主菜单和进入主循环操作,进行按键判断。
在判断键值时,有效的输入为本0至4之间的任意数值,其他输入都被视为错误按键并提示错误。若输入为0,系统会进去退出界面再执行退出通讯录管理系统的操作。
若选择1,则调用output()函数,显示所有通讯录;若选择2,则调用search ()函数,执行查询通讯录操作;若选择3,根据全局布尔类型的变量判断,若为0则调用input_password()函数,执行输入密码操作,若为1则调用admin()函数;若选择4,则调用about()函数,执行显示版权声明操作;若输入为0~9之外的值,给出按键错误的提示。
3.4.3 输出记录模块
输出记录模块主要实现将通讯录信息以表格的形式在屏幕上打印出来。通过文件指针以只读的方式打开文件,再用结构体申请临时空间,用fscanf逐条读出打印。
3.4.4 查询记录模块
查询记录模块分为三个模块:全名查询、模糊查找、号码查找。查询记录模块主要实现根据需求将以存入文件中的数据查找出来并打印。定义临时变量,用来记录需要查询的内容,通过文件指针以只读方式打开文件,再用结构体申请临时空间,用fscanf逐条读出文件内容,用strcmp或者strstr进行比对,相同则输出。
3.4.5 更新记录模块
模块主要实现了对学生记录的添加、修改、删除。
次要功能还有对系统的密码进行修改、格式化通讯录、重置系统、导出通讯录。
3.4.5.1 添加模块
添加模块主要实现将数据存入文件中。通过文件指针以追加的方式打开文件,再用结构体申请临时空间,输入需要添加的姓名和号码,在用fprintf输出到文件里面,关闭文件,释放空间。
3.4.5.2 修改模块
修改模块主要实现根据需要从文件中查找出所要修改的数据再对其进行修改。定义临时变量,用来记录需要修改的内容、文件位置,通过文件指针以可读写的方式打开文件,再用结构体申请临时空间,用long型的变量记录文件位置,再用scanf逐条读出数据。用strcmp进行比对,相同则用fseek进行定位修改。
3.4.5.3 删除模块
删除模块主要实现根据需要将其中的数据进行删除。定义一个新的文件指针dele,定义变量,用来记录需要删除的内容,通过文件指针分别以只读方式和只写方式打开两个文件。再用结构体申请临时空间,逐条读入只读文件的内容,用strcmp与需删除的进行比对,若不同则输出到只写文件中。用remove删除只读文件,再用dos命令对只写文件改名。
3.4.5.4 格式化通讯录
格式化通讯录主要实现将通讯录内容全部清除。通过文件指针以只写方式打开文件,实现格式化。
3.4.5.5 密码模块
密码模块主要实现一个验证身份的功能。通过一个全局的字符串数组实现,系统开始通过文件把密码读入数组,修改密码时又存入文件。输入密码时通过控制台函数库里面的getch来接收函数,再判断然后输出星号,实现密码隐藏功能。
3.4.5.6 导出模块
导出模块主要实现将通讯录以TXT格式保存在D盘,便于携带和复制。
3.4.5.6 重置模块
重置模块主要实现如果系统出现了一些未知BUG,可以便于用户恢复出场设置。通过以只写方式打开密码和存储信息的文件来使数据复原。
3.4.6 关于模块
关于模块主要实现对版权的声明。
3.4.7函数功能描述
void add(); //添加功能
void add_face(); //添加的界面
void admin(); //管理后台
void admin_face(); //后台界面
void all_name_face(); //全名查找界面
void all_name_search(); //全名查找功能
void amend(); //修改功能
void amend_face(); //修改功能界面
void bye_bye(); //退出界面
void creat(); //数据初始化
void del(); //删除功能
void del_all(); //格式化功能
void del_face(); //删除功能界面
void export(); //导出功能
void input_password(); //输入密码功能
void interface_header(); //界面的头部
void menu(); //菜单界面
void menu_header(); //逐渐输出的菜单头界面
void name_search(); //名字查找菜单
void name_search_face();//名字查找菜单界面
void num_face(); //号码查找界面
void num_search(); //号码查找功能
void output(); //输出功能
void part_name_face(); //模糊查找界面
void part_name_search();//模糊查找功能界面
void password_initialization();//实现密码初始化
void search(); //查找菜单
void search_face();
void set_password();
void setpwd_face();
void welcome();
void wel_menu();
void format();
void about();
//查找界面 //设置密码功能 //设置密码界面 //欢迎界面 //逐渐输出的菜单界面 //重置系统 //版权声明
3.5系统实现
3.5.1编码
3.5.1.1 程序预处理
包括加载头文件,定义结构体、常量和变量,并对它们进行初始化工作。 #include "stdio.h"
#include "conio.h"
#include "windows.h"
#include "string.h"
#include "stdlib.h"
//定义结构体
typedef struct friends
{
char name[10]; //姓名
char phone[15]; //号码
}friends;
//定义全局函数
FILE *fp;
char pwd[15]; //密码
bool EnterPwd_flag=0; //判断是否需要输入密码
3.5.1.2 主函数main()
main()函数主要实现了对整个程序的运行控制,以及相关功能模块的调用。 void main()
{
char ch; //定义变量用于选择
password_initialization();//加载密码初始化函数
welcome();//加载欢迎界面
creat();//加载信息初始化函数
wel_menu();//加载动态菜单头
while(1)//功能选择
{
menu();//加载菜单
goflag:while(1)
{
fflush(stdin);//清除输入缓存
if(kbhit())//判断是否有键按下
{
ch=getch();
break;
}
}
switch(ch)
{
case '1':output();break;//输出功能
case '2':search();break;//查询功能
case '3':
{
if(EnterPwd_flag) //判断是否需要输入密码
{
admin();//后台功能
break;
}
else
{
input_password();//密码输入
break;
}
}
case '4':about();break;//版权声明
case '0':bye_bye();exit(0);//退出
default: {
menu();
printf(" 没有这个选项请重新输入");
goto goflag;
}
}
}
}
3.5.1.3表格形式显示记录
由于记录显示操作经常进行,所以将这部分由独立的函数来完成,减少代码的重复。 void output()
{
}
interface_header();//调用界面头 friends *frd; frd=(friends *)malloc(sizeof(friends));//申请空间 if((fp=fopen("data.dat","r"))==NULL)//打开文件 { printf(" 通讯录加载失败\n"); printf(" 请您手动重启通讯录系统\n"); printf(" 系统将在2秒后自动关闭\n"); printf(" 给您带来不便,请谅解"); Sleep(2000); bye_bye(); exit(0); } printf("\n\n"); while(!feof(fp)) { fscanf(fp,"%s%s\n",(*frd).name,(*frd).phone);//逐条读出 printf("\t\t\t\t%-15s%-30s\n",(*frd).name,(*frd).phone);//打印 } fclose(fp);//关闭文件 free(frd);//释放空间 printf("\n\n 按任意键返回\n"); getch();//从键盘读取一个字符
3.5.1.4 查询记录
当用户执行此查询任务时,系统会提示用户进行查询字段的选择,即按号码或姓名进行查询。若此记录存在,则会打印输出此记录的信息。
//查找的功能菜单
void search()
{
char ch;
while(1)
{
search_face();//加载界面
goflag:while(1)
{
fflush(stdin);
if(kbhit())
{
ch=getch();
break;
}
}
switch(ch)
{
case '1':name_search();break;//进入姓名查找
case '2':num_search();break;//进入号码查找
case '0':return;
default: {
interface_header();
search_face();
printf(" 没有这个选项请重新输入"); goto goflag;
}
}
}
}
//姓名查找的功能菜单
void name_search()
{
char ch;
while(1)
{
name_search_face();//加载界面
goflag:
while(1)
{
fflush(stdin);
if(kbhit())
{
ch=getch();
break;
}
}
switch(ch)
{
case '1':all_name_search();break;//全姓名查找
case '2':part_name_search();break;//模糊查找
case '0':return ;
default: {
name_search_face();
printf(" 没有这个选项请重新输入"); goto goflag;
}
}
}
}
//全姓名查找
void all_name_search()
{
all_name_face();//加载界面
friends *frd;
bool n=0;//判断是否找到
char nam[10];//用于输入
if((fp=fopen("data.dat","r"))==NULL)
{
printf(" 通讯录加载失败\n");
printf(" 请您手动重启通讯录系统\n"); printf(" 系统将在2秒后自动关闭\n"); printf(" 给您带来不便,请谅解"); Sleep(2000);
bye_bye();
exit(0);
}
frd=(friends *)malloc(sizeof(friends));
printf(" 请输入您要查找的姓名:");
scanf("%s",nam);
printf("\t\t\t\t%-15s%-30s\n\n","姓名","号码");
while(!feof(fp))
{
fscanf(fp,"%s%s\n",(*frd).name,(*frd).phone);
if(!strcmp(nam,(*frd).name))//逐条比对
{
printf("\t\t\t\t%-15s%-30s\n",(*frd).name,(*frd).phone); n=1;//找到n变为1
}
}
free(frd);
fclose(fp);
if(n==0) printf("\n\t\t\t\t对不起,没有此人记录!\n");
printf("\n\t\t\t\t按任意键返回\n");
getch();
}
//模糊查找
void part_name_search()
{
part_name_face();
friends *frd;
bool n=0;
char nam[10];
if((fp=fopen("data.dat","r"))==NULL)
{
printf(" 通讯录加载失败\n");
printf(" 请您手动重启通讯录系统\n"); printf(" 系统将在2秒后自动关闭\n"); printf(" 给您带来不便,请谅解"); Sleep(2000);
bye_bye();
exit(0);
}
frd=(friends *)malloc(sizeof(friends));
printf(" 请输入您要查找的姓名关键字:"); scanf("%s",nam);
printf("\t\t\t\t%-15s%-30s\n\n","姓名","号码");
while(!feof(fp))
{
fscanf(fp,"%s%s\n",(*frd).name,(*frd).phone);
if(strstr((*frd).name,nam))//使用strstr实现部分匹配输出 {
printf("\t\t\t\t%-15s%-30s\n",(*frd).name,(*frd).phone); n=1;
}
}
free(frd);
fclose(fp);
if(n==0)
printf("\n\t\t\t\t对不起,没有此人记录!\n");
printf("\n\t\t\t\t按任意键返回\n");
getch();
}
//号码查找,原理与全名查找相同
void num_search()
{
num_face();
friends *frd;
bool n=0;
char num[15];
if((fp=fopen("data.dat","r"))==NULL)
{
}
printf(" 通讯录加载失败\n"); printf(" 请您手动重启通讯录系统\n"); printf(" 系统将在2秒后自动关闭\n"); printf(" 给您带来不便,请谅解"); Sleep(2000); bye_bye(); exit(0); } frd=(friends *)malloc(sizeof(friends)); printf(" 请输入您要查找的号码:"); scanf("%s",num); printf("\t\t\t\t%-15s%-30s\n\n","姓名","号码"); while(!feof(fp)) { fscanf(fp,"%s%s\n",(*frd).name,(*frd).phone); if(!strcmp(num,(*frd).phone)) { printf("\t\t\t\t%-15s%-30s\n",(*frd).name,(*frd).phone); n=1; } } free(frd); fclose(fp); if(n==0) printf("\n\t\t\t\t对不起,没有此人记录!\n"); printf("\n\t\t\t\t按任意键返回\n"); getch();
3.5.1.5增加记录
实现添加通讯录的功能。
void add()
{
add_face();//加载界面
friends *frd;
char ch;
frd=(friends *)malloc(sizeof(friends));
if((fp=fopen("data.dat","a"))==NULL)
{
printf(" 通讯录加载失败\n");
printf(" 请您手动重启通讯录系统\n"); printf(" 系统将在2秒后自动关闭\n"); printf(" 给您带来不便,请谅解");
}
Sleep(2000); bye_bye(); exit(0); } printf(" 请输入您要添加的姓名:"); scanf("%s",(*frd).name); printf(" 请输入您要%s的号码:",(*frd).name); scanf("%s",(*frd).phone); fprintf(fp,"%-15s%-30s\n",(*frd).name,(*frd).phone);//在文件中打印出来 fclose(fp); free(frd); printf("\n 号码添加成功\n"); printf("\n 继续添加请按Y,返回上一级请按其他键"); fflush(stdin); ch=getch(); if(ch=='y'||ch=='Y') add();
3.5.1.6 删除记录
在删除操作中,系统会按用户要求先找到该记录,然后从文件中删除。 void del()
{
FILE *dele;//定义一个新的文件指针
del_face();//加载界面
friends *frd;
char nam[10],y;
bool n=0;//判断是否删除
if((fp=fopen("data.dat","r+"))==NULL)//判断是否成功打开存档文件 {
printf(" 通讯录加载失败\n");
printf(" 请您手动重启通讯录系统\n");
printf(" 系统将在2秒后自动关闭\n");
printf(" 给您带来不便,请谅解");
Sleep(2000);
bye_bye();
exit(0);
}
if((dele=fopen("data2.dat","w"))==NULL)//建立一个新的存档文件 {
printf(" 通讯录加载失败\n");
printf(" 请您手动重启通讯录系统\n");
printf(" 系统将在2秒后自动关闭\n");
} printf(" 给您带来不便,请谅解"); Sleep(2000); bye_bye(); exit(0); } frd=(friends *)malloc(sizeof(friends)); printf(" 请输入您要删除的姓名:"); scanf("%s",nam); while(!feof(fp)) { fscanf(fp,"%s%s\n",(*frd).name,(*frd).phone);//读入存档文件信息 if(!strcmp(nam,(*frd).name))//判断是否为需要删除的文件 { n=1;//找到则改变其值 printf("\t\t\t\t%-15s%-30s\n\n","姓名","号码"); printf("\t\t\t\t%-15s%-30s\n",(*frd).name,(*frd).phone); printf("\n 是否对%s进行删除(Y/N)\n",(*frd).name); fflush(stdin); y=getch(); if(y=='y'||y=='Y')//判断是否确认删除 { printf(" 删除成功\n"); continue; } } fprintf(dele,"%-15s%-30s\n",(*frd).name,(*frd).phone);//输出到新文件中 } if(n) { } else //没找到删除人则输出 printf("\n\n 对不起,没有此人记录!\n"); fclose(fp);//关闭原记录文件 fclose(dele);//关闭新记录文件 free(frd); remove("data.dat");//删除原记录文件 system("ren data2.dat data.dat"); //运用DOS命令将新记录文件改名为原记录文件名 printf("\n 继续删除请按Y,返回上一级请按其他键"); fflush(stdin); y=getch(); if(y=='y'||y=='Y') del();
3.5.1.7 修改记录
在修改记录操作中,系统会先按输入的姓名查询到该记录,然后提示用户修改内容,进行修改。
void amend()
{
amend_face();//加载界面
friends *frd;
long offset;//定义变量来存储查找到的地址
char nam[10],y;
bool n=0;
if((fp=fopen("data.dat","r+"))==NULL)
{
printf(" 通讯录加载失败\n");
printf(" 请您手动重启通讯录系统\n");
printf(" 系统将在2秒后自动关闭\n");
printf(" 给您带来不便,请谅解");
Sleep(2000);
bye_bye();
exit(0);
}
frd=(friends *)malloc(sizeof(friends));
printf(" 请输入您要修改的姓名:");
scanf("%s",nam);
while(!feof(fp))
{
offset=ftell(fp);//获取地址
fscanf(fp,"%s%s\n",(*frd).name,(*frd).phone);
if(!strcmp(nam,(*frd).name))
{
n=1;break;
}
}
if(n)
{
printf("\t\t\t\t%-15s%-30s\n\n","姓名","号码");
printf("\n\t\t\t\t%-15s%-30s\n",(*frd).name,(*frd).phone);
printf("\n 是否对%s进行修改(Y/N)\n",(*frd).name);
fflush(stdin);
y=getch();
if(y=='y'||y=='Y')
{
printf(" 请您输入新的名字:");
scanf("%s",(*frd).name);
printf(" 是否对其密码进行修改,修改请按Y,按任意键不修改\n\n");
}
fflush(stdin); y=getch(); if(y=='y'||y=='Y') { printf(" 请您输入%s的新号码:",(*frd).name); scanf("%s",(*frd).phone); } fseek(fp,offset,SEEK_SET);//将指针定位到刚刚存储的地址 fprintf(fp,"%-15s%-30s\n",(*frd).name,(*frd).phone);//将修改信息打印文件 printf(" 修改成功\n"); } } else printf("\n\n 对不起,没有此人记录!\n"); fclose(fp); free(frd); printf("\n 继续修改请按Y,返回上一级请按其他键"); fflush(stdin); y=getch(); if(y=='y'||y=='Y') amend();
3.5.1.8 密码模块
密码模块的设置是为了实现保护用户的信息,需要进入增删改的时候需要用密码约束身份,本系统密码模块主要由密码初始化、输入密码、修改密码三部分构成。
3.5.1.8.1初始化密码
在初始化密码操作中,系统会判断用户是否第一次使用该系统,若是第一次,则会在欢迎界面之前让用户设定初始密码;若不是则从文件中读取密码存在全局变量当中。
void password_initialization()
{
int i;
char pwdkey[15];
char pwdkey_again[15];
if((fp=fopen("password.dat","r"))==NULL)//判断存储密码文件是否存在
{
pwdflag:system("cls");
i=0;
printf("\n\n\n\n\n\n\n\t\t\t 您第一次使用该系统\n");
printf("\t\t\t请为系统高级管理设置一个密码\n\n");
printf(" 初始化密码:");
while((pwdkey[i]=getch())!=13)//从键盘中读取一个字符,判断是否是回车 { if(i==0&&pwdkey[i]==8)//如果这是第一位数且输入的是退格则继续循环 continue; else if(pwdkey[i]==8)//判断是否是退格 { printf("\b \b");//取出一个星号 i--; } else { printf("*");//输出一个星号 i++;//位数自加 } }//实现输入的密码星号化 pwdkey[i]='\0'; printf("\n\n"); i=0; printf(" 确认密码: "); while((pwdkey_again[i]=getch())!=13) { if(i==0&&pwdkey_again[i]==8) continue; else if(pwdkey_again[i]==8) { printf("\b \b"); i--; } else { printf("*"); i++; } } pwdkey_again[i]='\0'; if(!strcmp(pwdkey,pwdkey_again))//比对两次输入的密码是否相同 { strcpy(pwd,pwdkey);//若相同则把密码复制到全局函数中 if((fp=fopen("password.dat","w"))==NULL)//建立密码保存文件 { printf(" 密码加载失败\n"); printf(" 请您手动重启通讯录系统\n"); printf(" 系统将在2秒后自动关闭\n"); printf(" 给您带来不便,请谅解");
}
Sleep(2000); bye_bye(); exit(0); } fprintf(fp,"%s",pwd);//输出到密码保存文件中 printf("\n\n 密码初始化成功\n"); getch(); } else //两次输入不同 { printf("\n\n 密码与确认密码不一致\n"); printf(" 按任意键重新输入"); getch(); goto pwdflag; } } else //若密码保存文件已存在 { fscanf(fp,"%s",pwd); //读取密码至全局变量 } fclose(fp);
3.5.1.8.2 输入密码
输入密码主要实现根据身份判断能不能实施高级操作。 void input_password()
{
interface_header();//加载界面头
char pwdkey[15];
int i=0;
printf("\n\n\n 请输入管理员密码:"); fflush(stdin);//清除输入缓存
while((pwdkey[i]=getch())!=13)
{
if(i==0&&pwdkey[i]==8)
continue;
else if(pwdkey[i]==8)
{
printf("\b \b");
i--;
}
else
{
}
printf("*"); i++; } } pwdkey[i]='\0'; if(!strcmp(pwdkey,pwd))//比对密码 { EnterPwd_flag=1; admin(); } else { printf("\n 密码有误,敲击键盘返回上一级"); getch(); }
3.5.1.8.3 修改密码
实现对密码的修改。
void set_password()
{
setpwd_face();//加载界面 int i=0;
char pwdkey[15];
char pwdkey_again[15];
printf(" 输入新密码:"); while((pwdkey[i]=getch())!=13) {
if(i==0&&pwdkey[i]==8) continue;
else if(pwdkey[i]==8) {
printf("\b \b");
i--;
}
else
{
printf("*");
i++;
}
}
pwdkey[i]='\0';
printf("\n\n");
} i=0; printf(" 确认密码: "); while((pwdkey_again[i]=getch())!=13) { if(i==0&&pwdkey_again[i]==8) continue; else if(pwdkey_again[i]==8) { printf("\b \b"); i--; } else { printf("*"); i++; } } pwdkey_again[i]='\0'; if(!strcmp(pwdkey,pwdkey_again)) { strcpy(pwd,pwdkey); if((fp=fopen("password.dat","w"))==NULL)//用读写方式打开文件 { printf(" 密码加载失败\n"); printf(" 请您手动重启通讯录系统\n"); printf(" 系统将在2秒后自动关闭\n"); printf(" 给您带来不便,请谅解"); Sleep(2000); bye_bye(); exit(0); } fprintf(fp,"%s",pwd); printf("\n\n 密码修改成功\n"); fclose(fp); EnterPwd_flag=0;//将判断是否需要再次输入密码进入高级菜单的变量至0 } else printf("\n\n 密码与确认密码不一致\n"); printf(" 敲击键盘返回上一级"); getch();
3.5.1.9 导出功能
将存入的文件复制到D盘并且打开。
void export()
{
FILE *in,*out;//声明两个文件指针
interface_header();//载入界面头
if((in=fopen("data.dat","r"))==NULL)
{
printf(" 通讯录加载失败\n");
printf(" 请您手动重启通讯录系统\n");
printf(" 系统将在2秒后自动关闭\n");
printf(" 给您带来不便,请谅解");
Sleep(2000);
bye_bye();
exit(0);
}
if((out=fopen("D:/通讯录.txt","w"))==NULL)//在D盘新建通讯录.txt文件 {
printf(" 通讯录加载失败\n");
printf(" 请您手动重启通讯录系统\n");
printf(" 系统将在2秒后自动关闭\n");
printf(" 给您带来不便,请谅解");
Sleep(2000);
bye_bye();
exit(0);
}
while(!feof(in))fputc(fgetc(in),out);//逐个字符输出到out文件中
fclose(in);
fclose(out);
printf("\n\n\n 导出成功\n\n");
system("D:/通讯录.txt");//用dos命令打开文件
printf(" 按任意键返回");
getch();
}
3.5.1.9 重置功能
新建文件将原来的密码存储文件和信息存储文件覆盖实现恢复出厂设置。代码与之前的大致相同,就不多做注释。
void format()
{
char y;
int i=0;
char pwdkey[15];
char pwdkey_again[15];
interface_header();
printf("\n 通讯录系统重置会清除您现有通讯录\n");
printf("\n 继续重置请按Y,返回上一级请按其他键\n\n"); fflush(stdin);
y=getch();
if(y=='y'||y=='Y')
{
if((fp=fopen("data.dat","w"))==NULL)
{
printf(" 通讯录重置失败\n");
printf(" 请您手动重启通讯录系统\n");
printf(" 系统将在2秒后自动关闭\n");
printf(" 给您带来不便,请谅解");
Sleep(2000);
bye_bye();
exit(0);
}
fprintf(fp,"%-15s%-30s\n","姓名","号码");
fclose(fp);
if((fp=fopen("password.dat","w"))==NULL)
{
printf(" 密码重置失败\n");
printf(" 请您手动重启通讯录系统\n"); printf(" 系统将在2秒后自动关闭\n"); printf(" 给您带来不便,请谅解");
Sleep(2000);
bye_bye();
exit(0);
}
pwdflag:interface_header();
i=0;
printf("\n\n 输入重置密码:");
while((pwdkey[i]=getch())!=13)
{
if(i==0&&pwdkey[i]==8)
continue;
else if(pwdkey[i]==8)
{
printf("\b \b");
i--;
}
else
{
} printf("*"); i++; } } pwdkey[i]='\0'; printf("\n\n"); i=0; printf(" 确认密码: "); while((pwdkey_again[i]=getch())!=13) { if(i==0&&pwdkey_again[i]==8) continue; else if(pwdkey_again[i]==8) { printf("\b \b"); i--; } else { printf("*"); i++; } } pwdkey_again[i]='\0'; if(!strcmp(pwdkey,pwdkey_again)) { strcpy(pwd,pwdkey); fprintf(fp,"%s",pwd); printf("\n\n 密码重置成功\n"); } else { printf("\n\n 密码与确认密码不一致\n"); printf(" 按任意键重新输入\n"); getch(); goto pwdflag; } } fclose(fp); printf(" 按任意键返回"); getch();
3.5.1.10 后台菜单
实现对增删改功能函数的调用。
void admin()
{
char ch;
while(1)
{
admin_face();//加载界面
goflag:
while(1)
{
fflush(stdin);
if(kbhit())
{
ch=getch();
break;
}
}
switch(ch)
{
case '1':add();break;//添加
case '2':amend();break;//修改
case '3':del();break;//删除
case '4':del_all();break;//格式化
case '5':export();break;//导出
case '6':set_password();break;//设置密码
case '7':format();break;//重置系统
case '0':return;//返回上一级
default: {
admin_face();
printf(" 没有这个选项请重新输入"); goto goflag;
}
}
}
}
3.5.1.11 界面模块
界面模块实现使得系统更加美观,实现为了每个功能都有相应的界面。 //输出一个欢迎界面
void welcome()
{
int i;
system("cls"); for(i=0;i<10;i++) { switch(i) { case 0:printf("\n\n\n\n\n\n\n\n\n\n case 1:printf("\n\n\n\n\n\n\n\n\n\n case 2:printf("\n\n\n\n\n\n\n\n\n\n case 3:printf("\n\n\n\n\n\n\n\n\n\n case 4:printf("\n\n\n\n\n\n\n\n\n\n case 5:printf("\n\n\n\n\n\n\n\n\n\n case 6:printf("\n\n\n\n\n\n\n\n\n\n case 7:printf("\n\n\n\n\n\n\n\n\n\n case 8:printf("\n\n\n\n\n\n\n\n\n\n case 9:printf("\n\n\n\n\n\n\n\n\n\n } Sleep(100); //系统延迟100毫秒 if(i==9)break; system("cls"); //清屏 } system("cls"); for(i=9;i>=0;i--) { switch(i) { case 0:printf("\n\n\n\n\n\n\n\n\n\n case 1:printf("\n\n\n\n\n\n\n\n\n\n case 2:printf("\n\n\n\n\n\n\n\n\n\n case 3:printf("\n\n\n\n\n\n\n\n\n\n case 4:printf("\n\n\n\n\n\n\n\n\n\n case 5:printf("\n\n\n\n\n\n\n\n\n\n case 6:printf("\n\n\n\n\n\n\n\n\n\n case 7:printf("\n\n\n\n\n\n\n\n\n\n case 8:printf("\n\n\n\n\n\n\n\n\n\n case 9:printf("\n\n\n\n\n\n\n\n\n\n } Sleep(100); system("cls"); } }
//输出一个退出界面 void bye_bye() {
w");break; we");break; wel");break; welc");break; welco");break; welcom");break; welcome");break; welcome.");break; welcome..");break; welcome...");break;
w");break; we");break; wel");break; welc");break; welco");break; welcom");break; welcome");break; welcome.");break; welcome..");break; welcome...");break;
int i; system("cls"); for(i=0;i<10;i++) { switch(i) { case 0:printf("\n\n\n\n\n\n\n\n\n\n case 1:printf("\n\n\n\n\n\n\n\n\n\n case 2:printf("\n\n\n\n\n\n\n\n\n\n b");break; by");break; bye");break; case 3:printf("\n\n\n\n\n\n\n\n\n\n case 4:printf("\n\n\n\n\n\n\n\n\n\n case 5:printf("\n\n\n\n\n\n\n\n\n\n case 6:printf("\n\n\n\n\n\n\n\n\n\n case 7:printf("\n\n\n\n\n\n\n\n\n\n case 8:printf("\n\n\n\n\n\n\n\n\n\n case 9:printf("\n\n\n\n\n\n\n\n\n\n } Sleep(100); if(i==9)Sleep(500); system("cls"); } for(i=9;i>-1;i--) { switch(i) { case 0:printf("\n\n\n\n\n\n\n\n\n\n case 1:printf("\n\n\n\n\n\n\n\n\n\n case 2:printf("\n\n\n\n\n\n\n\n\n\n case 3:printf("\n\n\n\n\n\n\n\n\n\n case 4:printf("\n\n\n\n\n\n\n\n\n\n case 5:printf("\n\n\n\n\n\n\n\n\n\n case 6:printf("\n\n\n\n\n\n\n\n\n\n case 7:printf("\n\n\n\n\n\n\n\n\n\n case 8:printf("\n\n\n\n\n\n\n\n\n\n case 9:printf("\n\n\n\n\n\n\n\n\n\n } Sleep(100); system("cls"); } printf("\n\n\n\n\n\n\n\n\n\n\t\t\t }
//逐渐输出的界面头 void menu_header() {
bye~");break; bye~b");break; bye~by");break; bye~bye.");break; bye~bye..");break; bye~bye...");break; bye~bye....");break;
b");break; by");break; bye");break; bye~");break; bye~b");break; bye~by");break; bye~bye.");break; bye~bye..");break; bye~bye...");break; bye~bye....");break;
");
int i;
system("cls");
printf("\n\n 欢迎使用通讯录系统\n"); for(i=0;i<40;i++)
{
printf("%c%c",0XA9,0XA4);
Sleep(20);
}
printf("\n");
}
//界面头
void interface_header()
{
int i;
system("cls");
printf("\n\n 欢迎使用通讯录系统\n"); for(i=0;i<40;i++)
printf("%c%c",0XA9,0XA4);
printf("\n");
}
//查找的界面
void search_face()
{
interface_header();
printf(" [1] 按姓名查找\n\n"); printf(" [2] 按号码查找\n\n"); printf(" [0] 返回上一级\n\n"); }
//姓名查找的界面
void name_search_face()
{
interface_header();
printf(" [1] 按全部姓名查找\n\n"); printf(" [2] 按部分姓名查找\n\n"); printf(" [0] 返回上一级\n\n"); }
//全姓名查找的界面
void all_name_face()
{
interface_header();
printf(" 全名查找\n\n"); }
//模糊查找的界面
void part_name_face()
{
interface_header();
printf(" 模糊查找\n\n"); }
//号码查找的界面
void num_face()
{
interface_header();
printf("
}
//后台的主界面
void admin_face()
{
interface_header();
printf("
printf("
printf("
printf("
printf("
printf("
printf("
printf("
}
//添加通讯录的界面
void add_face()
{
interface_header();
printf("
}
//修改通讯录的界面
void amend_face()
{
interface_header();
printf("
} 号码查找\n\n"); [1] 添加通讯录\n\n"); [2] 修改通讯录\n\n"); [3] 删除通讯录\n\n"); [4] 格式化通讯录\n\n"); [5] 将通讯录导出到D盘\n\n"); [6] 修改管理员密码\n\n"); [7] 重置通讯录系统\n\n"); [0] 返回上一级\n\n"); 添加通讯录\n\n"); 修改通讯录\n\n");
//删除通讯录的界面
void del_face()
{
interface_header();
printf(" 删除通讯录\n\n"); }
//修改密码的界面
void setpwd_face()
{
interface_header();
printf("
}
//逐渐输出的主菜单
void wel_menu()
{
menu_header();
printf("
Sleep(50);
printf("
Sleep(50);
printf("
Sleep(50);
printf("
Sleep(50);
printf("
Sleep(50);
}
//主菜单界面
void menu()
{
interface_header();
printf("
printf("
printf("
printf("
printf("
}
//版权声明
void about() 修改密码\n\n"); [1] 显示全部\n\n"); [2] 查找菜单\n\n"); [3] 高级功能\n\n"); [4] 关于系统\n\n"); [0] 退出系统\n\n"); [1] 显示全部\n\n"); [2] 查找菜单\n\n"); [3] 高级功能\n\n"); [4] 关于系统\n\n"); [0] 退出系统\n\n");
{
}
interface_header(); printf("\n\t\t\t ********************************\n"); printf("\t\t\t * *\n"); printf("\t\t\t * 通讯录系统 *\n"); printf("\t\t\t * *\n"); printf("\t\t\t * 制作人:顾越东 *\n"); printf("\t\t\t * *\n"); printf("\t\t\t * QQ: 240438457 *\n"); printf("\t\t\t * *\n"); printf("\t\t\t * 按任意键返回 *\n"); printf("\t\t\t * *\n"); printf("\t\t\t * *\n"); printf("\t\t\t ********************************\n"); getch();
3.5.2测试与调试
3.5.2.1概述
一般情况下,为解决一个问题所编写的程序代码较长,可能包括几百条甚至成千上万条语句。在检查并排除所有语法错误后,还会有不易发现的逻辑错误,因此要对程序进行认真仔细的测试与调试。
测试是通过运行程序发现错误的过程,常见的错误有数据溢出、数组越界、进入死循环、语句顺序颠倒、多加“;”或少加“{}”等等。调试则是确定测试中找到的错误性质并改正错误的过程。测试与调试通常交替进行,即测试——调试——再测试——再调试。
能检查出尚未发现的、各种不同类型错误的测试才是成功的测试。测试程序需要测试用例,测试用例可用如下公式表示:测试用例=测试数据+预期结果。
好的测试用例应该是用尽可能少的测试数据发现尽可能多的错误,即发现错误的概率要大。要选择合适的测试数据,使系统在运行时尽量能执行到每条语句,以测试各指令是否正确。还应分别测试输入合法数据与非法数据时,程序的运行情况,。对于合法数据,还要考虑数据的一般性与特殊性,如求最大值的问题,应测试最大值在最前面、最后面、中间某一位置的情况。
测试可按模块测试、组装测试和确认测试的步骤进行。
(1)模块测试就是分别对各模块进行测试的过程。在编写一个模块后应立即对其进行测试,因为这时对模块记忆深刻,而且单个模块相对较小,所以容易构造测试数据,能方便地检查和改正错误。
(2)组装测试就是把所有模块(应该是通过模块测试的模块)按预先制定的计划逐步组装和测试的过程。一般情况下,各模块之间要相互传递数据和控制信息,因此组装测试的主要任务是发现模块接口中的错误。
(3)确认测试是最后一个步骤,一般在将软件交付用户之前,应确认软件是否确实满足用户的要求,通常使用接近实际的用例进行测试。
Visual C++环境下测试程序可以用以下的方法。
● 临时加打印语句,将所要观察的数据显示在屏幕上。
F5热键单步执行程序。
● 综合使用以上方法。
测试程序时,用监视窗口可以随时查看变量或表达式的值,有时还可以将部分程序
代码用注释符暂时括起来,缩短程序,以便压缩出错代码的范围。
● 设置断点用
3.5.2.2程序测试
制定调试计划,制定的计划中要把预想的任何情况全部制定出来,争取全部语句都能跑一边,以判断是否错误,再对程序进行运行,逐项测试。
四、系统维护
经测试与调试确认软件无错时,开发就告一段落,这时可以交付软件供用户使用,但是在软件的使用过程中还会面临更加漫长的工作,即软件维护。一般维护的工作有:更改使用中发现的错误;为适应实际环境而对程序进行修改;为满足新的需求而对程序作必要的改进等等。
五、归纳总结
5.1 开发经验
通过对本题目的开发,体会到要掌握以下几点内容。
? 大程序的设计风格。按“自顶向下,逐步细化,模块化”的方法进行程序设计。 ? 编写主函数,并进行测试与调试。当被调函数又需要调用其他函数时,也要遵循逐
步细化的原则。C语言提供丰富的库函数,编程序时要善于使用库函数,避免不必
要的劳动。
? 定义函数时,应选好参数的个数和数据类型。
? 文件使用方法。文件使用完毕后应及时关闭。
5.2 实训中遇到的问题及解决方法
在这次的实训中,主要遇到的问题是编译环境的不同对程序也不同。因为TC的库函数较为丰富,我们所用的编译系统的VC所以有些使用的函数在VC中会出现编译错误,比如头文件getpass.c,函数textcolor()。
5.3 设计中尚存的不足之处
关于这次的程序,也有挺多不足的地方。程序的身份验证功能较为单一,不能实现多用户分层管理的,也没设定遗忘密码后的补救方法,使得可能给用户带来不便。
5.4 感想和心得体会
通过这次实训,我感触甚深,要把所学的理论知识运用于解决实际问题不仅要付出艰辛的劳动,还得要有科学的方法和坚持不懈的努力。这次实训让我进一步理解了“编程是什么”,“如何去编程”,“编程的目的又是什么”,??发现自己的知识竟是如此贫乏,顿时感到了压力的存在,从而也激发了我的学习热情。它会成为我今后不断进取、永不懈怠的动力。
在整个实训过程中,我能够坚持虚心的向老师以及同学请教问题,它使我明白了虚心好学的重要性,更让我懂得了如何跟老师同学去相处、去沟通。没有老师和同学们的无私帮助,我不可能圆满完成这次实训任务。感谢帮助过我的所有老师和同学们,要列出所有帮助过我的人的名字是不现实的,因为有些困难是通过因特网解决的,我甚至不知道他们的名字,在此,谨向他们一并表示感谢!
六、参考资料
谭浩强 C程序设计(第三版) 清华大学出版社
K&R C primer plus(第五版) 人民邮电出版社