在线等大神 小型小区来访人员管理系统课程设计问题
还有两天就要去答辩了,实在是找不到原因,还望大神们指导一二,鄙人不胜感激。代码可以运行,唯一的缺陷就是查询全部信息的时候得到的结果是:众多地方发生二次读取(我也不知道可不可以这样叫,暂且这样叫吧)
查询结果如下:
代码贴出,还望大神们浪费一点点时间给小弟指条路。。
程序代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h> //exit()的头文件
#include<conio.h> //屏幕操作函数
#define N 100 //控制人员记录的容量
void menu();
void browse();
typedef struct person
{
char number[4]; //序号
char ymd[10]; //来访日期
char v_name[10]; //来访人姓名
char cre_name[10]; //来访人证件名
char c_num[18]; //来访人证件编号
char bv_name[10]; //被访人姓名
double f_num; //被访人楼号
char hm_start[5]; //来访时间
char hm_leave[5]; //离开时间
char desc[20]; //备注
}PER;
PER per[N]; //定义一个外部结构体变量
/*****以写的方式保存数据到文件的函数【原数据将被覆盖】*****/
int save(int n) //保存函数,保存n个记录
{
FILE *fp;
int i;
if((fp=fopen("zhouhao.txt","wb"))==NULL)//以二进制写的方式打开,在此前的记录被覆盖
{
printf("无法打开文件!\n任意键退出程序... ...\n");
getch(); //预防闪屏
return 0;
}
for(i=0;i<n;i++)
if(per[i].f_num!=0) //在后面的del()函数中通过将per[i].f_num=0来表示该记录被删除了
if(fwrite(&per[i],sizeof(struct person),1,fp)!=1)//开始写入文件
printf("文件写入发生错误\n");
fclose(fp);
return 0;
}
/***【加载记录或可以计算记录个数的函数】***/
int load()
{
FILE *fp;
int i;
if((fp=fopen("zhouhao.txt","rb"))==NULL) //以二进制读的方式打开
{
printf("无法打开文件!\n任意键退出程序... ...\n"); //显示不能打开文件的信息
getch(); //预防闪屏
return 0;
}
for(i=0;!feof(fp);i++)
fread(&per[i],sizeof(struct person),1,fp); //将文件数据读入学生结构体
fclose(fp);
return(i-1); //返回目前总的记录个数
}
/***【一个任务结束时的选择浏览还是返回的函数】***/
void printf_back()
{
int w;
printf("\n\t操作成功!\n");
printf("\t请选择:\n\t1).立刻浏览全部信息。\t2).返回:[ ]\b\b");
scanf("%d",&w);
if(w==1)
browse();
else
menu();
}
/***【显示数据结构项目函数】***/
void printf_face()
{
printf("\n序号|");
printf(" 来访日期 |");
printf("来访人姓名|");
printf("来访人证件名称|");
printf(" 来访人证件编号 |");
printf("被访人姓名|");
printf("被访人楼号|");
printf("来访时间|");
printf("离开时间|");
printf("\t\t备注\t\t|\n");
}
/***【输入一整条记录的函数】***/
void input(int i)
{
printf("请输入序号:");
scanf("%s",&per[i].number);
printf("请输入来客日期(格式为2014-06-25):");
scanf("%s",&per[i].ymd);
printf("请输入来客姓名:\n");
scanf("%s",&per[i].v_name);
printf("请输入来客证件名:\n");
scanf("%s",&per[i].cre_name);
printf("请输入来客证件编号:\n");
scanf("%s",&per[i].c_num);
printf("请输入被访人姓名:\n");
scanf("%s",&per[i].bv_name);
printf("请输入被访人楼号:\n");
scanf("%d",&per[i].f_num);
printf("请输入来访时间(格式为00:00):\n");
scanf("%s",&per[i].hm_start);
printf("请输入离开时间(格式为2014-06-25 00:00):\n");
scanf("%s",&per[i].hm_leave);
printf("请输入备注:\n");
scanf("%s",&per[i].desc);
}
/***【显示一整条记录的函数】***/
void printf_one(int i)
{
printf("\n%4s|%10s|%10s|%14s|%18s|%10s|%10d|%8s|%8s|%20s\n",per[i].number,per[i].ymd,per[i].v_name,per[i].cre_name,per[i].c_num,per[i].bv_name,per[i].f_num,per[i].hm_start,per[i].hm_leave,per[i].desc);
}
/*【显示----函数顶部】*/
void topput_()
{
printf("\n 记 录 浏 览 ");
printf("\n--------------------------------------------------------------------------------\n");
}
/*【显示----函数底部】*/
void puts_()
{
printf("\n\n--------------------------------------------------------------------------------\n");
}
/*【修改记录函数】*/
int modify_data(int i,int n)
{
int c,w1;
do
{
puts("\n您准备修改下列哪种情况:\n1).序号\t2).来访日期\t3).来访人姓名\t4).来访人证件名\t5).来访人证件编号\t6).被访人姓名\t7).被访人楼号\t8).来访时间\t9).离开时间\t10).备注\t11).重新输入所有记录\t12).取消并返回\n");
printf("请输入您的选择:[]\b\b\b");
scanf("%d",&c);
if(c>12 || c<1)
{
puts("\n您的选择有误,请重新选择!");
getchar();
}
}while(c>12 || c<1);
do
{
switch(c)
{
case 1:printf("请输入序号:");scanf("%s",&per[i].number);break;
case 2:printf("来访日期(格式为2014-06-25):");scanf("%s",per[i].ymd);break;
case 3:printf("来访人姓名:");scanf("%s",per[i].v_name);break;
case 4:printf("来访人证件名:");scanf("%s",per[i].cre_name);break;
case 5:printf("来访人证件编号:");scanf("%s",per[i].c_num);break;
case 6:printf("被访人姓名:");scanf("%s",per[i].bv_name);break;
case 7:printf("被访人楼号:");scanf("%d",per[i].f_num);break;
case 8:printf("来访时间(格式为00:00):");scanf("%s",per[i].hm_start);break;
case 9:printf("离开时间(格式为2014-06-25 00:00):");scanf("%s",per[i].hm_leave);break;
case 10:printf("备注:");scanf("%s",per[i].desc);break;
case 11:input(i);break;
case 12:menu();
}
puts("\n修改后的数据位:\n");
printf_face();
printf_one(i);
printf("\n您确定要修改本条信息?\n\t1).确定\t2).重新修改\t3).不保存![]\b\b\b");
scanf("%d",&w1);
}while(w1==2);
return w1;
}
/* * * * * * * * * * * * 输入模块 * * * * * * * * * * * */
void enter()
{
int i,n;
system("CLS");
printf("请输入您要录入信息的人员数量:(1-%d?\t['0'返回]:\n",N);
scanf("%d",&n);
/*------判断n的值,调用相应的函数进行操作------*/
if(n==0)
menu();
else
{
for(i=0;i<n;i++)
{
input(i);//调用输入函数
}
if(i!=0)
save(n);//调用保存函数
printf_back();//一个任务完成后让操作员来选择是浏览还是返回
}
}
/*******************************增加模块*************************************/
int add()
{
int i,n,m,k;
FILE *fp;
system("CLS");
n=load(); //获取总记录的个数,并加载记录
printf("您需要添加多少个访问者的信息:(0-%d)?:",N-n);
scanf("%d",&m); //追加记录的个数
if(m==0)
menu();
else
{
k=m+n;
for(i=n;i<k;i++)
{
printf("\n请输入第%d个访问者的记录。\n",i-n+1);
input(i);
}
if((fp=fopen("manage.txt","ab"))==NULL) //以ab方式打开,添加信息并保存
{
printf("文件打不开!\n");
getch();
return 0;
}
for(i=n;i<k;i++)
if(fwrite(&per[i],sizeof(struct person),1,fp)!=1)
printf("文件写入错误!\n");
fclose(fp);
printf_back();
}
return 0;
}
/***************************** 修改模块 *************************/
void modify()
{
struct person p;
int i,n,k,w0=0,w1,w2=0;
n=load(); //获得总记录的个数,并加载记录
do
{
system("CLS");
k=-1;
/*********给用户看所有记录以便用户确认要修改的记录***********/
topput_();
printf_face();
for(i=0;i<n;i++)
printf_one(i);
puts_();
/*********给用户看所有记录以便用户确认要修改的记录***********/
do
{
printf("\n\n请输入您要修改记录的序号!序号:\t【'Ctrl-z' 退出】");
if(scanf("%s",p.number)!=1)
menu();
for(i=0;i<n;i++)
if(strcmp(p.number,per[i].number)==0)
{
k=i;
p=per[i];
}
if(k==-1)
printf("\n您所要修改的信息不存在,请重新输入!");
}while(k==-1);
printf_face();
printf_one(k);
w1=modify_data(k,n);
if(w1==1)
{
printf("\n操作成功!\n确定要修改该条信息?\n1).确定\t2).返回\t[ ]\b\b\b");
scanf("%d",&w0);
w2=1;
}
else
{
w0=0;
if(w2==1)
per[k]=p;
}
if(w0!=1 && w2==1)
save(n);
}while(w0==1);
menu();
}
/*******************************删除模块 *************************/
void del()
{
struct person p;
int i,k,n,c,w0=1;
system("CLS");
n=load();
do
{
system("CLS");
k=-1;
topput_();
printf_face();
for(i=0;i<n;i++)
if(per[i].f_num!=0)
printf_one(i);
puts_();
do
{
printf("\n请输入您要删除记录的来访人姓名:\t【'Ctrl-z' 返回】");
if(scanf("%s",p.v_name)!=1)
menu();
for(i=0;i<n;i++)
if(strcmp(p.v_name,per[i].v_name)==0)
{
k=i;
p=per[i];
}
if(k==-1)
printf("\n您所要修改的信息不存在,请重新输入!");
}while(k==-1);
puts("\n");
printf_face();
printf_one(k);
printf("\n确定要删除该条信息?\n\t1).确定\t2).修改其他信息\t3).返回[ ]\b\b\b");
scanf("%d",&c);
if(c==1)
{
per[k].f_num=0;
printf("\n操作成功!\n您要继续删除信息吗?\n\t1).继续修改\t2).返回主菜单\t[ ]\b\\b\b");
scanf("%d",&w0);
}
if(c==3)
w0=0;
if(w0!=0 && c!=3)
save(n);
}while(w0==1);
menu();
}
/**************************************浏览(全部)模块*****************************************/
void browse()
{
int i,n;
n=load();
system("CLS");
topput_();
printf_face();
for(i=0;i<n;i++)
printf_one(i);
puts_();
printf("\n\t这里一共有%d条记录!\n",n);
printf("\n\t按任意键返回主菜单!\n");
getch();
menu();
}
/*******************************查找模块************************************/
void search()
{
int i,n,k,w1=1,w2,w3,w4;
struct person p;
system("CLS");
n=load();
do
{
do
{
k=-1;
printf("\n请输入您要查找的被访人姓名:\n");
scanf("%s",p.bv_name);
printf_face();
for(i=0;i<n;i++)
if(strcmp(p.bv_name,per[i].bv_name)==0)
{
k=i;
printf_one(k);
}
if(k==-1)
{
printf("\n您所要查找的信息不存在,请重新输入!");
printf("\n要继续查找吗?\n\t1).继续\t2).返回\t[ ]\b\b\b");
scanf("%d",&w1);
}
}while(k==-1 && w1!=2);
w4=w3=0;
if(k!=-1)
{
printf("\n还要查看信息吗?\n\t1).再次查找\t2).修改信息\t3).删除\t4).返回主菜单\t[ ]\b\b\b");
scanf("%d",&w2);
switch(w2)
{
case 2:w3=modify_data(k,n);break;
case 3:{
printf("\n\t1).确定2).返回\t[ ]\b\b\b");
scanf("%d",&w4);
if(w4==1)
per[k].f_num=0;
break;
}
}
if(w3==1 || w4==1)
{
save(n);
printf("\n操作成功");
printf("\n\t1).再次查找2).返回[]\b\b");
scanf("%d",&w2);
}
}
}while(w2==1);
menu();
}
/*******************************排序模块(按照被访人的楼号)*********************************/
void order()
{
int i,j,k,n;
struct person p;
system("CLS"); //清屏
n=load(); //获得总记录的个数,并加载记录
for(i=0;i<n-1;i++)
{
k=i;
for(j=i+1;j<n;j++)
if(per[j].f_num>per[k].f_num) //选择法排序
k=j;
p=per[i];
per[i]=per[k];
per[k]=p;
}
save(n);
puts("\n\n");
printf_back();
}
/**********************************主界面************************************/
void menu(){
int n,w1;
do
{
system("CLS");
puts("\n\t\t\t小型小区来访人员登记管理系统");
puts("\t\t * * * * * * * * * * * * * * * * * * * * * ");
puts("\t\t *\t 1. 基本信息录入\t\t *");
puts("\t\t *\t 2. 添加新信息 \t\t *");
puts("\t\t *\t 3. 根据来访人姓名删除记录\t *");
puts("\t\t *\t 4. 根据来访人姓名修改记录\t *");
puts("\t\t *\t 5. 查看浏览记录信息\t\t *");
puts("\t\t *\t 6. 根据被访人楼号查询记录\t *");
puts("\t\t *\t 7. 按照被访人楼号进行排序\t *");
puts("\t\t *\t 8. 退出管理系统\t\t *");
puts("\t\t * * * * * * * * * * * * * * * * * * * * * ");
/*-------输入选择编号----------*/
printf("\t请输入您的选择(1-8):[ ]\b\b");
scanf("%d",&n);
/*-------判断输入数是否在1-8之间------*/
if(n <= 0 || n > 8)
{
w1=1;
printf("\t对不起,您的选择不在1-8之间,请重新输入!");
getch();
}else
w1=0;
}while(w1==1);
/*----选择编号,利用switch语句-----*/
switch(n)
{
case 1:enter();break;
case 2:add();break;
case 3:modify();break;
case 4:del();break;
case 5:browse();break;
case 6:search();break;
case 7:order();break;
case 8:exit(0);break;
}
}
/************************************主函数***************************************/
void main()
{
menu();
}
[ 本帖最后由 小菜笔 于 2014-6-30 23:09 编辑 ]










调试了一早上,知道问题出在了从文本中读取那步骤,我用的以二进制的读取方式,这个和直接文本读取有什么区别呢?还望尊贵的斑斑大人指导一下。