| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 532 人关注过本帖
标题:在线等大神 小型小区来访人员管理系统课程设计问题
只看楼主 加入收藏
小菜笔
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2014-6-30
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:8 
在线等大神 小型小区来访人员管理系统课程设计问题
还有两天就要去答辩了,实在是找不到原因,还望大神们指导一二,鄙人不胜感激。
代码可以运行,唯一的缺陷就是查询全部信息的时候得到的结果是:众多地方发生二次读取(我也不知道可不可以这样叫,暂且这样叫吧)
查询结果如下:



代码贴出,还望大神们浪费一点点时间给小弟指条路。。

程序代码:
#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 编辑 ]
搜索更多相关主题的帖子: 信息 课程 在线 不胜感激 人员管理 
2014-06-30 22:43
小菜笔
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2014-6-30
收藏
得分:0 
不知道怎么发图片,还望大神们运行看看。。。谢谢了。。。
2014-06-30 22:44
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
发生了“二次读取”,问题肯定在相关的读取部分,把那部分分离出来检查。而之所以“众多地方”都出现同样的问题,那么应该是同一个读取函数出了问题,把检查的注意力放在多次使用过的函数上。找原因、解决问题,都要用分析法,乱找当然效率低。另一方面,写出来的代码也要方便排错,这早应该是平时写代码练习时就要训练的——可惜现在大多数学编程的人都不重视这一点。

[ 本帖最后由 TonyDeng 于 2014-7-1 08:31 编辑 ]

授人以渔,不授人以鱼。
2014-07-01 08:30
funyh250
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:26
帖 子:290
专家分:1573
注 册:2013-12-25
收藏
得分:0 
用异常机制
try一个

学习是大事   吃喝拉撒睡是小事   其他的那都不是事
2014-07-01 10:37
小菜笔
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2014-6-30
收藏
得分:0 
回复 4 楼 funyh250
调试了一早上,知道问题出在了从文本中读取那步骤,我用的以二进制的读取方式,这个和直接文本读取有什么区别呢?还望尊贵的斑斑大人指导一下。
2014-07-01 12:27
小菜笔
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2014-6-30
收藏
得分:0 
回复 3 楼 TonyDeng
谢谢斑斑大大,由于基础不太扎实,最初学习文件读取这部分的时候,老师舍掉了这部分内容,我自己当时也只是略读了一下。
还望斑斑大大,给我讲一下用二进制读取和直接文本读取有什么不同?那个出错的几率小点?
2014-07-01 12:30
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
    for(i=0;!feof(fp);i++)
        fread(&per[i],sizeof(struct person),1,fp);                    //将文件数据读入学生结构体

又是feof()的问题咯,早几天坛上才有帖子专门解释这个东西,自己搜索看看。有空看看别人的帖么,光盯着自己的看有什么用,这样坐等到明年也不是办法呀。

授人以渔,不授人以鱼。
2014-07-01 12:34
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:20 
二进制的快一点,但是可移植性差一点;文本的与之相反。出错几率是一样的,基本上都栽在文件结束处的读取上。不要用feof()判断循环结束,直接用fread()的返回值,比如你的代码,那个计数器参数(count)是1,则如果读到文件结束处,就读不到1个数据项,其返回值是零(凡是读不完全的,返回值都不等于计数器之值),此时就该结束循环了。另一方面,不要直接把读入的数据储存在per[i],先读到一个中间变量中,判断fread()是否成功,只有成功了,才把这个中间变量的数据赋值给per[i],这样就不会有垃圾数据进入。

[ 本帖最后由 TonyDeng 于 2014-7-1 12:48 编辑 ]

授人以渔,不授人以鱼。
2014-07-01 12:47
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
不是所有生成文件的方式都写入文件结束标志,不一定的,所以不要试图用读到文件结束符的方法来判断文件尾,因为那可能成功,也可能不成功,偶然的成功反而会误导你以为方法正确。而不使用中间变量直接向最终目标灌输正确性未知的数据(在读取外部设备数据时尤其未知是否正确),则只会增加回退处理的麻烦——原则上,凡是取舍未定的数据都不应直接放入数据序列。

授人以渔,不授人以鱼。
2014-07-01 12:57
快速回复:在线等大神 小型小区来访人员管理系统课程设计问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.027848 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved