C语言课程设计:医院管理系统

文末附有源码。

实验说明:

《程序设计基础课程设计》

1、编写一个C语言程序,实现一个医院的诊疗管理系统,能够管理至少30位患者,每位患者至多30条诊疗记录。其中:

1)每条诊疗记录包括患者信息、医生信息、诊疗情况三部分。请自行组织相关信息的存储方式(冗余信息可不存储)和显示格式。
2)患者信息包括:姓名、年龄、挂号;挂号唯一。
3)医生信息包括:姓名、级别、科室、工号、出诊时间;工号唯一;每位医生只在规定时间出诊(如每周一、周三,默认出诊即全天出诊)。
4)诊疗情况分为3类信息:检查、开药、住院。对于检查,仅记录每种检查费用,以及所有检查的总费用;对于开药,仅记录每种药品名称、单价、数量,以及所有药品的总价;对于住院,仅记录住院开始日期、预计出院日期、住院押金。
5)住院费用按实际天数计算。在办理住院时(即开始日期)需要交纳住院押金,住院押金要求为100元的整数倍,且不低于200*N(N为拟住院天数)元。特殊约定:在00:00-08:00之间办理出院不收取当天的住院费。对于拟继续住院的患者则系统会自动在08:00从患者的住院押金中扣除当天的住院费用,患者住院期间需随时保证住院押金一直不低于1000元。

为了简化,特做如下约定:

1)如涉及时间,仅包括月、日、时、分(默认为当年)。
2)患者最多100位,医生最多30位;药品最多30种,药品充足;患者每次开药最多100盒(或其它合适的数量单位)。
3)医生的级别限定为:主任医师、副主任医师、主治医师、住院医师1,尽可能符合实际情况。医生仅隶属于某个科室。提醒:医生之间、患者之间、医生患者之间均可能重名。
4)每天,医院可最多受理500个号,每位医生可最多受理20个号,每位患者可最多挂5个号、同一科室最多挂1个号;需自行设计挂号的编码规则,可隐含挂号日期、挂号当天的顺序号、对应的医生等信息,保证每条诊疗记录的挂号唯一。
5)金额要精确到元、角、分,不允许有误差,最高额度不超过10万;最大数量不超过int允许最大整数。

具体功能要求如下:

0)开始时,管理系统默认医院的运营资金为0元。
1)【增加】能够从文件中录入多条诊疗记录,也能够随时录入1条诊疗记录。注意:需要考虑各种类型的不规范、不合理或错误数据,如:数据位数不对、格式不对等。【重点考察】
2)【修改】能够随时修改1条诊疗记录。按照财务规范,如需修改错误的诊疗记录,应将当前错误的诊疗记录予以撤销后,再补充添加正确的诊疗记录。【重点考察】
3)【删除】能够随时删除1条诊疗记录。
1 住院医师只是医生的一种级别,并不表示诊疗情况中的住院只能与住院医师对应。
4)【查询】能够按照合理顺序打印某个科室的诊疗信息(按照科室检索)。
5)【查询】能够按照合理顺序打印某位医生的诊疗信息(按照医生的工号检索)。
6)【查询】能够按照合理顺序打印某位患者的历史诊疗信息(按照患者的相关信息检索)。
7)【统计】能够统计医院目前的营业额(检查费用+药品费用+住院费用,不含住院押金);能够生成目前的住院患者报表。【重点考察】
8)【统计】能够统计每位医生的出诊情况和工作繁忙程度。
9)【某段时间范围】能够打印某段时间范围内的所有诊疗信息。【重点考察】
10)【存储】能够将当前系统中的所有信息保存到文件中。
11)其它你认为有用的附加功能,可酌情添加。

源码

注:该源码脱离资源文件不能运行,运行请下载附件中的工程文件

//文件basic.h
#ifndef OPEN_H_INCLUDED
#define OPEN_H_INCLUDED
struct Doctor{
	int number;//工号
	char name[20];//姓名
	int level; //级别
	int department;//科室
	int workingHours[7];//工作时间。索引值0~6对应周日~周六,存储值为1则为上班,0则为不上班
	struct Doctor *next;
	int registed;//今日挂号量统计
	int w_registed;//周挂号量统计
};
struct ExaminationFee{
		char name[20];
		int cost;
		struct ExaminationFee *next;
	};
struct Medicine{
		int number;
		char name[20];
		int price;
		struct Medicine *next;
	};
struct Hospitalization{
		int zhuyuanyajin;//住院押金
		int ruyuanshijian;//入院时间:月、日、时、分
		int chuyuanshijian;//出院时间:月、日、时、分
	};
struct Treatment{
	int total;
	int totalExaminationFee; //总检查费
	struct ExaminationFee exminationFee;

	int totalMedicineCharge; //总药费
	struct Medicine medicine;
	struct Hospitalization hospitalization;
};
/*数据类*/
struct Data{
	int number;		//挂号序列  需是唯一值
	int ID;//患者ID,对于每位患者来说是唯一值
	char name[20]; //患者姓名
	int age;		//患者年龄
	struct Doctor doctor;		//医生
	struct Treatment treatment; //治疗方法
	struct Data *next;//链
};
int clearMedList();//回收药品链表内存
int clearDoctorList();//回收医生链表
int clearExamList();//回收诊疗项目链表内存

void saveData(char *location);//在location路径下将dataHead链表的所有数据存储到文件中
int registe();//挂号模块
void inputMedData();//从文件中读取并加载药品仓库数据
void buildDoctorList();//加载医生值班数据
int compStr(char *s1, int len1, char *s2, int len2);//字符串比对函数,用于检索
void buyMedicine(struct Data* newnode);//购药函数
int printDeparList(int n);//输出某个科室的情况
void hospitalize(struct Data* newNode);//住院模块
void selectExaminations(struct Data * newnode);//选择检查项目
void menu();//主菜单
int viewData();//浏览数据模块

void inputExamData();//加载所有的检查项目
void clearList1(struct Medicine *base);//回收base链表内存
void clearList2(struct ExaminationFee * base);//回收base链表内存
int findExamStart(int left, int right, FILE *pf_exam, int target); //二分查找,在文件中寻找对应的购药数据
int findMedStart(int left, int right, FILE *pf_med, int target); //二分查找,在文件中寻找对应的检查项目数据
int buildMedList(struct Medicine *base, FILE *pf_med, int start, int end);//建立诊疗记录中的购药单链表
int buildExamList(struct ExaminationFee *base, FILE *pf_exam, int start, int end);//建立诊疗记录中的检查项目链表
void clearList(struct Data *base);//回收base链表内存
struct Data* input(const char *dir);//建立链表的主函数,文件路径为dir,返回值为哨兵节点
void openUTDfile();//打开最新的数据文件
int preDay(char *ori);//输入为"data/1009/"型字符串,输出为前一天的字符串,如“data/1008/”
int nextDay(char *ori);//输入为"data/1009/"型字符串,输出为后一天的字符串,如“data/1010/”
int scanInt(int *num, int length);//输入整型变量,回车键结束输入,非法字符会被忽略,输入过长返回-2,无输入返回-1;
int scanStrNum(char *num,int length);//输入数字的字符串,回车键结束输出,非法字符会被忽略,若无符合要求的输入则返回1,长度过长返回-2.
int scanName(char *s, int length);//输入姓名,返回-2为输入过长
void loadHospitalizeData();//加载住院数据
void saveHosData();//存储主链表数据
int inputDate(int *month, int *day);//输入日期的函数
struct Data* reInput(const char* dir);//从路径为dir的文件中倒序建立链表
int viewUTDdata(int n);//浏览最新的n条数据
int showDepartStatus();//显示挂号情况模块
void showDocRegisted(struct Doctor *head);//显示科室中所有医生的情况
int leaveHospital(struct Data *p);//出院模块
int timeSpan(int start, int end);//日期不合法返回0
int printfMoneyStatus();//打印医院的营业额
void w_countAllDoc();//统计所有医生近一周的挂号量
int scanStr(char *s, int length);//安全读取字符串的函数
int dataChangeMenu();//数据修改菜单
int changeDataMenu();//修改数据的主界面
int setPassWord();//加密函数
char * deCode();//解密函数
int dataViewMenu(); //数据浏览模块
int inpatientDapart();//住院部模块
int patientAdminMenu();//住院病人管理菜单
int delayTime(struct Data *p);//延期出院模块
int  printMargin(int n) ;//用于排版
void loading() ;//加载动效
int printSingleData(struct Data *p);//打印单条数据
int saveMedData();
int reSeek(FILE *pf);

#endif // OPEN_H_INCLUDED

//文件basic.c
#include 
#include 
#include
#include
#include 
#include 
#include 
#include
#include"basic.h"
#include"view.h"
#include"change.h"

/*
设定:每个医生一天最多挂10个号
每个科室最多挂20个号
*/
const char DoctorLevel[5][12] = {"","住院医师","主治医师","副主任医师","主任医师"};
struct Medicine * mediStorage;//医院药品仓库
struct ExaminationFee * examlists; //医院所有可检查的项目
struct Data* dataHead;//链表头结点.有哨兵
struct Data* dataRear;//链表尾结点
struct Data* inHospital;//所有正在住院的病人,无哨兵
struct Data* inHospitalRear;
struct Doctor doctor_departments[5];//设置5个科室,每个科室都是一个医生链表,有哨兵结点
char departments[7][20] = {"内科","外科","儿科","五官科","传染病科"};
int countDepartment[7];//记录每个科室挂了多少号
int sequence = 1;//挂号序列

/*考虑:几种模式的浏览:*/

int viewData()
{
    system("cls");
    printf("\n\n\n\n\n");
    printMargin(40);
    printf("1、浏览最新数据\n\n");
    printMargin(40);
    printf("2、浏览历史数据\n\n");
    printMargin(40);
    printf("0、返回上一层\n\n\n\n\n");
    printf("请选择:");
    int command;
    for(;;)
    {
            scanInt(&command, 3);
            if((command < 0)||(command > 3))
            {
                printf("输入非法!\n请重新输入:");
            }
            else
                break;

    }
    if(!command)
        return 0;
    if(command == 1)
    {
        printf("请输入要查看多少条数据(最多100条):");
        for(;;)
        {
            scanInt(&command, 4);
            if((command < 0)||(command > 100))
            {
                printf("输入非法\n请重新输入:");
            }
            else
                break;
        }
        viewUTDdata(command);
    }
    else
        viewDataSpan();
    return 0;
}


struct Data* input(const char* dir)//打开以路径“dir”为参数的所有文件,路径格式:“data/1001/”
{
    FILE *pf, *pf_med, *pf_exam;
    char position[40];
    strcpy(position,dir);
    strcpy(position+10,"data.txt");
    sequence = 0;
    struct Data *  base =  (struct Data*)malloc(sizeof(struct Data));
	base->next = NULL;
    if(pf = fopen(position,"r"),pf==NULL)
    {

        dataRear = base;
        dataHead = base;
        return base;
    }
    strcpy(position+10,"examination.txt");
    pf_exam = fopen(position,"r");
    strcpy(position+10,"medicine.txt");
	pf_med = fopen(position,"r");
	struct Data *p1, *p2 = NULL;
	p1 = base;
	struct Data *ptmp = NULL;
	while(!feof(pf))
	{
		p2 = (struct Data *)malloc(sizeof(struct Data));
		p2->next = NULL;
		p1->next = p2;
		fscanf(pf,"%d%d%s%d%d%s",&(p2->number),&(p2->ID),p2->name,&(p2->age),&(p2->doctor.number),p2->doctor.name);
		fscanf(pf,"%d%d",&p2->doctor.level,&p2->doctor.department);
		int i;
		for(i = 0; i < 7; ++i)
		fscanf(pf,"%d",&(p2->doctor.workingHours[i]));
		fscanf(pf,"%d",&(p2->treatment.total));
		int med_start,med_end,exam_start,exam_end;
		fscanf(pf,"%d%d%d%d",&med_start,&med_end,&exam_start,&exam_end);
		fscanf(pf,"%d%d",&(p2->treatment.hospitalization.ruyuanshijian),&(p2->treatment.hospitalization.chuyuanshijian));
		p2->treatment.medicine.next = NULL;

		fgetc(pf);
		p2->treatment.totalMedicineCharge = buildMedList(&(p2->treatment.medicine),pf_med,med_start,med_end);
		p2->treatment.totalExaminationFee = buildExamList(&(p2->treatment.exminationFee), pf_exam,exam_start,exam_end);
		ptmp = p1;
		sequence = (ptmp->number)%10000;
		p1 = p2;
	}
	dataRear = ptmp;
	ptmp->next = NULL;

	free(p2);
	fclose(pf);
	fclose(pf_exam);
	fclose(pf_med);
	return base;

}



/*建立购药单链表*/
int buildMedList(struct Medicine *base, FILE *pf_med, int start, int end)//建立药品链表(需要读取购药单所在的文件)
{
    base->next = NULL;
	if(start > end)
	return 0;
    if(!start)
    return 0;
    int totalcost = 0;
    int right;
	fseek(pf_med,-38,SEEK_END);//共有right条数据
	fscanf(pf_med,"%d",&right);
	--right;
	struct Medicine *p1, *p2;
	p1 = (struct Medicine *)malloc(sizeof(struct Medicine)); //文件尾记录了总共有多少条数据,8字节
	base->next = p1;
	p1->next = NULL;
	int s;
	s = findMedStart(0, right, pf_med,start);//二分查找开始的记录
	fseek(pf_med,s * 38, SEEK_SET);
	int tmp;
	fscanf(pf_med,"%d%s%d%d",&(tmp),p1->name,&(p1->price),&(p1->number));
    totalcost += ((p1->price) * (p1->number));
	if(start > end)
        return 0;
	while((tmp < end)&&(!feof(pf_med)))
	{
		p2 = (struct Medicine*)malloc(sizeof(struct Medicine));
		p2->next = NULL;
		p1->next = p2;
		p1 = p2;
		fscanf(pf_med,"%d%s%d%d",&tmp,p1->name,&(p1->price),&(p1->number));
		totalcost += ((p1->price) * (p1->number));
	}
	return totalcost;
}
/*寻找购药单起点*/
int findMedStart(int left, int right, FILE *pf_med, int target)
{
	int mid = (left + right) / 2;
	fseek(pf_med,mid * 38, SEEK_SET);
	int tmp;
	fscanf(pf_med,"%d",&tmp);
	if(tmp == target)
	return mid;
	if(left > right)
	return -1;
	if(tmp > target)
		return findMedStart(left,mid - 1, pf_med,target);
	else
		return findMedStart(mid + 1,right , pf_med, target);
}

/*建立检查项目链表*/
int buildExamList(struct ExaminationFee *base, FILE *pf_exam, int start, int end)
{
    base->next = NULL;
    int total = 0;
    if(end < start)
        return total;
    if(!end)
        return total;
    int right;
	fseek(pf_exam,-29,SEEK_END);
	fscanf(pf_exam,"%d",&right);
	--right;
	struct ExaminationFee *p1, *p2;
	p1 = (struct ExaminationFee *)malloc(sizeof(struct ExaminationFee)); //文件尾记录了总共有多少条数据,8字节
	base->next = p1;
	int s;
	s = findExamStart(0, right, pf_exam,start);//二分查找开始的记录
	fseek(pf_exam,s * 30, SEEK_SET);
	int tmp;
	fscanf(pf_exam,"%d%s%d",&tmp,p1->name,&(p1->cost));
	total += (p1->cost);
	p1->next = NULL;
	while((tmp < end)&&(!feof(pf_exam)))
	{
		p2 = (struct ExaminationFee*)malloc(sizeof(struct ExaminationFee));
		p1->next = p2;
		p1 = p2;
		fscanf(pf_exam,"%d%s%d",&(tmp),p1->name,&(p1->cost));
		total += (p1->cost);
		p2->next = NULL;
	}

	return total;
}
/*在检查项目总文件中寻找需要的数据段*/
int findExamStart(int left, int right, FILE *pf_exam, int target)
{
	int mid = (left + right) / 2;
	fseek(pf_exam,mid * 30, SEEK_SET);
	int tmp;
	fscanf(pf_exam,"%d",&tmp);
	if(tmp == target)
	return mid;
	if(left > right)
	return -1;
	if(tmp > target)
		return findExamStart(left,mid - 1, pf_exam,target);
	else
		return findExamStart(mid + 1,right , pf_exam, target);
}

/*释放总诊疗记录链表*/
void clearList(struct Data *base)
{
    if(!base)
        return;
	struct Data *p = base->next;
	free(base);
	struct Data *p2;
	while(p)
	{
		p2 = p;
		p = p->next;
		clearList2(p2->treatment.exminationFee.next);
		clearList1(p2->treatment.medicine.next);
		free(p2);
	}
	return;
}


/*释放购药链表*/
void clearList1(struct Medicine *base)
{
	struct Medicine *p = base;
	struct Medicine *p2;
	while(p)
	{
		p2 = p;
		p = p->next;
		free(p2);
	}
	return;
}
/*释放诊疗记录链表*/
void clearList2(struct ExaminationFee *base)
{
	struct ExaminationFee *p = base;
	struct ExaminationFee *p2;
	while(p)
	{
		p2 = p;
		p = p->next;
		free(p2);
	}
	return;
}

int printSingleData(struct Data * p)
{
        printf("挂号序列:%d 患者姓名:%s ID:%d 患者年龄: %d  ", p->number, p->name,p->ID, p->age);
        printf("医生:%s %s %s 工号:%d\n药品费: %d元 %d角\n",departments[p->doctor.department],DoctorLevel[p->doctor.level],p->doctor.name,p->doctor.number,(p->treatment.totalMedicineCharge)/10,(p->treatment.totalMedicineCharge)%10);
        printMedList(&(p->treatment.medicine));
        printf("检查费: %d元 %d角",(p->treatment.totalExaminationFee)/10,(p->treatment.totalExaminationFee)%10);
        printExamList(&(p->treatment.exminationFee));
        if(p->treatment.hospitalization.ruyuanshijian)
        {
            int a = p->treatment.hospitalization.ruyuanshijian;
            int b = p->treatment.hospitalization.chuyuanshijian;
            printf("入院时间:%d月 %d日 %d时",a /1000000,(a%1000000)/10000, (a%10000)/100);
            printf("出院时间:%d月 %d日 %d时",b /1000000,(b%1000000)/10000, (b%10000)/100);
        }
        printf("\n\n\n\n");
        return 0;
}


/*将dataHead链表的所有信息存在路径为location的文件中*/
void saveData(char *location)
{
    strcpy(location+10,"data.txt");
    FILE *pf_data = fopen(location,"w");
    strcpy(location+10,"examination.txt");
    FILE *pf_exa = fopen(location,"w");
    strcpy(location+10,"medicine.txt");
    FILE *pf_med = fopen(location,"w");
    struct Data * p = dataHead->next;
    int k_med = 1,k_exa = 1;
    while(p)
    {
        fprintf(pf_data,"%09d %08d %8s %03d %06d %8s %d %02d ",p->number,p->ID,p->name,p->age,p->doctor.number,p->doctor.name,p->doctor.level,p->doctor.department);
        for(int i = 0; i < 7; ++i)
        fprintf(pf_data,"%d ",p->doctor.workingHours[i]);
        fprintf(pf_data,"%06d ",p->treatment.total);
        struct Medicine* p_med = p->treatment.medicine.next;
        if(p_med)
        {
            fprintf(pf_data,"%06d ",k_med);
        while(p_med)
        {
            fprintf(pf_med,"%06d %20s %03d %04d\n",k_med++,p_med->name,p_med->number,p_med->price);
            p_med = p_med->next;
        }
        fprintf(pf_data,"%06d ",k_med-1);
        }
        else
        {
        fprintf(pf_data,"%06d %06d ",0,0);
        }
        struct ExaminationFee* p_exa = p->treatment.exminationFee.next;
        if(p_exa)
        {
            fprintf(pf_data,"%06d ",k_exa);
        while(p_exa)
        {
            fprintf(pf_exa,"%06d %14s %06d\n",k_exa++,p_exa->name,p_exa->cost);
            p_exa = p_exa->next;
        }
        fprintf(pf_data,"%06d ",k_exa-1);

        }
        else
        {
            fprintf(pf_data,"%06d %06d ",0, 0);
        }
        fprintf(pf_data,"%08d %08d\n",p->treatment.hospitalization.ruyuanshijian,p->treatment.hospitalization.chuyuanshijian);
        p = p->next;

    }
    fclose(pf_data);
    fclose(pf_exa);
    fclose(pf_med);

}

/*建立一个药品链表:该链表存储着医院所有药品*/
void inputMedData()
{
    FILE *pf_med = fopen("hospital/medicine.txt","r");

    mediStorage = (struct Medicine *)malloc(sizeof(struct Medicine));
     struct Medicine * p = mediStorage,*p1,*p2;
    while(!feof(pf_med))
    {
        p1 = (struct Medicine *)malloc(sizeof(struct Medicine));
        int tmp;
        fscanf(pf_med,"%d%s%d%d",&tmp,p1->name,&(p1->number),&(p1->price));
        p1->next = NULL;
        p->next = p1;
        p2 = p;
        p = p1;
    }
    free(p);
    p2->next = NULL;
    fclose(pf_med);

}


int clearMedList()
{
    struct Medicine * p = mediStorage,*p1;
    while(p)
    {
        p1 = p;
        p = p->next;
        free(p1);
    }
    return 0;
}
/*在每一个科室之下建立医生链表*/
void buildDoctorList()//
{
    FILE *pf_doctor = fopen("hospital/doctor.txt","a+");
    struct Doctor *p1[5], *p2;
    for(int i = 0; i < 5; ++i)
        p1[i] = &(doctor_departments[i]);
    while(!feof(pf_doctor))
    {
        p2 = (struct Doctor*) malloc(sizeof(struct Doctor));
        p2->next = NULL;
        fscanf(pf_doctor,"%s%d%d%d",p2->name,&(p2->level), &(p2->department),&(p2->number));
        for(int i = 0; i < 7; ++i)
            fscanf(pf_doctor,"%d",&(p2->workingHours[i]));
        p1[(p2->department)-1]->next = p2;
        p1[(p2->department)-1] = p2;
    }
}

int clearDoctorList()
{
    for(int i = 0; i < 5; ++i)
    {
        struct Doctor * p = doctor_departments[i].next, *p1;
        while(p)
        {
            p1 = p;
            p = p->next;
            free(p1);
        }
    }
    return 0;
}

int compStr(char *s1, int len1, char *s2, int len2)//字符串比对,返回匹配度
{
    int count = 0;
    for(int i = 0; i < len1; ++i)
    {
        for(int j = 0; j < len2; ++j)
        {
            if(s1[i] == s2[j])
            {
                ++count;
                break;
            }
        }
    }
    return count==len1;
}


/*患者的购药函数*/
void buyMedicine(struct Data* newnode)
{
    char s[20];
    struct Medicine *p1 = &newnode->treatment.medicine,*p2;
    newnode->treatment.totalMedicineCharge = 0;
    for(;;)
    {
        int flag = 0;
        printf("请输出欲购买药品的名称,输入exit退出购药界面\n输入:");
        scanStr(s,19);
        if(s[0]=='e')
            break;
        if(strlen(s) < 3)
        {
            printf("检索的关键词过短!");
            continue;
        }
        struct Medicine * container[100];
        int itr = 0;
        struct Medicine *p = mediStorage->next;//p是药仓,p1p2是新建链表
        printf("\n\n\n");
        while(p)
        {
            if(compStr(s,strlen(s),p->name,strlen(p->name)))
            {
                flag = 1;
                container[itr++] = p;
                printMargin(5);
                printf("%d、%s 单价 %d 元 %d 角 库存剩余 %d\n\n",itr, p->name, p->price/10, p->price%10, p->number);
            }
            p = p->next;
        }
        container[itr] = NULL;
        if(!flag)
            {
                printf("并没有找到该药品,请重新输入\n");
                continue;
            }
        printf("请选择欲购买药品的序号:");
        int command;
        for(;;)
        {
            scanInt(&command, 3);
            if((command < 1)||(command > itr))
                printf("输入不合法,请重新输入:");
            else
                break;
        }
        p = container[command-1];
        printf("您要购买:\n%s 单价 %d 元 %d 角 库存剩余 %d\n", p->name, p->price/10, p->price%10, p->number);
              for(;;)
        {
            printf("请输入数量:");
            scanInt(&command, 3);
            if((command < 0)||(command > p->number)||(command > 99))
                printf("输入不合法,请重新输入:");
            else
                break;
        }
        if(!command)
        {
            printf("继续购买请输入1,结束购买请输入0:");
            for(;;)
            {
                scanInt(&command, 3);
                if((command < 0)||(command > 1))
                {
                    printf("非法输入,请重新输入:");
                }
                else
                    break;
            }
            if(command == 0)
                break;
        }
        else
        {
            p2 = (struct Medicine *)malloc(sizeof(struct Medicine));
            p2->number = command;
            p2->next = NULL;
            p2->price = p->price;
            p1->next = p2;
            p->number -= command;
            newnode->treatment.totalMedicineCharge += (command* p->price);
            strcpy(p2->name,p->name);
            p1 = p2;
        }

        itr = -1;
        printf("继续购买请选择1,结束购买请选择0");
        for(;;)
        {
            scanInt(&command, 2);
            if((command < 0)||(command > 1))
            {
                printf("输入非法,请重新输入:");
            }
            else
                break;

        }
        if(command == 0)
            break;

    }

    printMedList(&newnode->treatment.medicine);
    return ;
}


/*打印出某个科室的所有值班医生(不值班的不会被打印)*/
int printDeparList(int n)
{
    if(countDepartment[n] >= 20)
{
    printMargin(40);
    printf("该科室患者已经达到上限20\n");
    return -1;
}
    printf("\n\n\n");
    printMargin(40);
    printf("该科室目前有%d位患者\n\n\n",countDepartment[n]);
    struct Doctor * p = doctor_departments[n].next;
    time_t rawtime;
    time(&rawtime);
    struct tm *ti = localtime(&rawtime);
    printMargin(40);
    printf("%s坐诊医生如下:\n\n\n",departments[n]);
    int ii = 0;
    while(p)
    {
        if(p->workingHours[ti->tm_wday])
        {
        printMargin(40); printf("|  %d:医生:%s %s",++ii,p->name,DoctorLevel[p->level]);
        printf("   目前有%d名患者\n",p->registed);
        printMargin(40);printf("|\n");
        }
        p = p->next;
    }
    printMargin(44);

    return 0;
}
/*挂号函数*/
int registe()
{
    countAllDoc();
    printfMoneyStatus();
    time_t timep;
    time(&timep);
    char location[20] = "data/";
    strftime(location+5,sizeof(location),"%m%d",localtime(&timep));
    if ( access(location, F_OK) != 0)
         {
             mkdir(location);
         }
    location[9] = '/';
    int money = 0;
    openUTDfile();//这里建立最新数据的链表。需要统计各个科室、各个医生挂了多少号
    FILE *pf_money = fopen("data/money.txt","r");
    fscanf(pf_money,"%d",&money);
    fclose(pf_money);
    for(;;)
    {
        struct Data * newNode = (struct Data*) malloc(sizeof(struct Data));
        newNode->next = NULL;
        newNode->treatment.totalExaminationFee = 0;
        newNode->treatment.totalMedicineCharge = 0;
        newNode->treatment.hospitalization.zhuyuanyajin = 0;
        printf("正在挂号...\n\n");
        time_t now;
        struct tm* tm_now;
        time(&now);
        tm_now = localtime(&now);
        int seq = (tm_now->tm_mon+1) * 10e6 + tm_now->tm_mday * 10e4;
        seq += (++sequence);
        printf("挂号序号:%d\n",seq%1000);
        newNode->number = seq;
        int command = 0;
        int m;
        struct Doctor * p;
        for(;;)
        {
            printf("\n\n\n\n\n\n\n\n");
        for(int i = 0; i < 5; ++i)
        {
            printMargin(40);printf("%d,%s",i+1,departments[i]);
            printf("   目前有患者%d人\n\n",countDepartment[i]);
        }
        printf("\n\n\n\n\n\n\n\n请选择(输入0则返回主菜单):");
        scanInt(&m,2);
        if((m > 5)||(m <0))
        {
            printf("请正确输入!\n");
            continue;
        }
        if(m == 0)
            {
                system("cls");
                return 0;
            }
        p = doctor_departments[m-1].next;
        system("cls");
        if(printDeparList(m-1) == 0)
            {
                break;
            }
        }

        int n;
        while(1)
        {
            printf("\n\n\n");
            printMargin(10);
            printf("请输入医生序号,输入0则返回上一层(医生的患者上限为10人):");
            scanInt(&command,3);
            n = command;
            if(n < 0)
            {
                printf("请正确输入\n");
                continue;
            }
            if(n == 0)
            {
                free(newNode);
                break;
            }
            p = doctor_departments[m-1].next;
            while(p)
            {
            if((p->workingHours[tm_now->tm_wday]))
            {
                if(!(--n))
                break;
            }
            p = p->next;
            }
            if(p == NULL)
            {
                printf("请正确输入\n");
                continue;
            }
            if(p->registed >= 10)
            {
                printf("该医生患者数已达上限\n");
                continue;
            }
            else
            {
                ++(p->registed);
                break;
            }
        }
        if(!command)
            continue;
        system("cls");
        printf("%s\n",p->name);
        strcpy(newNode->doctor.name,p->name);
        newNode->doctor.department = m;
        newNode->doctor.level = p->level;
        newNode->doctor.number = p->number;
        newNode->doctor.next = NULL;
        for(int i = 0; i < 7; ++i)
        newNode->doctor.workingHours[i] = p->workingHours[i];
        printf("请输入身份码(8位数字):");

        while((scanInt(&(newNode->ID),8)!= 8))
        {
            printf("请检查输入长度!重新输入!\n");
        }
        int num = countPatientDoc(newNode->ID,newNode->doctor.number);
        if(num)
        {
            printf("注意:您今天在%s 下已有挂号\n",newNode->doctor.name);
            printf("如要取消本次挂号请输入0,否则输入其他数字\n");
            scanInt(&command,2);
            if(command == 0)
            {
                    free(newNode);
                    continue;
            }
        }
        countDepartment[newNode->doctor.department]++;
        printf("请输入患者姓名 :");
        scanName(newNode->name,10);

        for(;;)
        {
            printf("请输入性别,0为女,1为男\n");
            int sex;
            scanInt(&sex,3);
            if((sex > 1)||(sex < 0))
                printf("请正确输入\n");
            else
                {
                    newNode->number += (sex * 10000);
                    break;
                }
        }


        for(;;)
        {
        printf("请输入年龄 :");
        scanInt(&(newNode->age),5);
        if((newNode->age > 150)||(newNode->age< 0))
        {
            printf("请检查输入!\n");
        }
        else
        {
            break;
        }
        }
        newNode->treatment.medicine.next = NULL;
        newNode->treatment.exminationFee.next = NULL;
        printf("如需购药请输入1, 输入其他数字则不购药\n");
        newNode->treatment.totalExaminationFee = 0;
        newNode->treatment.totalMedicineCharge = 0;
        newNode->treatment.total = 0;
        scanInt(&command,3);
        if(command == 1)
            buyMedicine(newNode);
        else
            newNode->treatment.medicine.next = NULL;
        printf("如需进行检查请输入1,否则输入其他数字\n");
        scanInt(&command,3);
        if(command == 1)
            selectExaminations(newNode);
        else
            newNode->treatment.exminationFee.next = NULL;
        printf("如需住院请输入1,否则输入其他数字\n");
        scanInt(&command,3);
        newNode->treatment.hospitalization.chuyuanshijian = 0;
        newNode->treatment.hospitalization.ruyuanshijian = 0;
        newNode->treatment.hospitalization.zhuyuanyajin = 0;
        if(command == 1)
            hospitalize(newNode);
                dataRear->next = newNode;
                dataRear = dataRear->next;
        printf("挂号成功!\n");
        saveData(location);
        printf("序号:%d  姓名:%s ",newNode->number,newNode->name);
        printf(" ID %d 年龄 %d 医生:%s\n\n",newNode->ID,newNode->age,newNode->doctor.name);
        printf("输入1继续挂号,输入0退出挂号系统\n");
        money += newNode->treatment.totalExaminationFee;
        money += newNode->treatment.totalMedicineCharge;
        money += newNode->treatment.hospitalization.zhuyuanyajin * 10;
        scanInt(&command,1);
        if(!command)
            break;
    }

    int moneyy = money;
    pf_money = fopen("data/money.txt","w");
    fprintf(pf_money,"%d",moneyy);
    fclose(pf_money);
    printfMoneyStatus();
    printf("按任意键返回\n");
    getchar();
    system("cls");
    clearList(dataHead);
    return 0;
}



int nextDay(char *ori)//输入为"data/1009/"型字符串,输出为后一天的字符串,如“data/1010/”
{
    if(ori[8]=='0')
        {
            ori[8]='1';
            return 0;
        }
    if(ori[7] == '3')//肯定为31号
    {
        ori[7] = '0';
        ori[8] = '1';
        ori[6] += 1;
        return 0;
    }
    if(ori[8] == '9')
        {
            ori[8] = '0';
            ori[7] += 1;
            return 0;
        }
    ori[8] += 1;
    return 0;
}
int preDay(char *ori)//输入为"data/1009/"型字符串,输出为前一天的字符串,如“data/1008/”
{
    if((ori[7] == '0')&&(ori[8] == '1'))
       {
           ori[7] = '3';
           ori[8] = '1';
           if(ori[6]=='0')
           {
               ori[6] = '9';
               ori[5] -= 1;
           }
           else
           {
               ori[6] -= 1;
           }
           return 0;
       }
    if(ori[8] == '0')
    {
        ori[8] = '9';
        ori[7] -= 1;
        return 0;
    }
    ori[8] -= 1;
    return 0;

}

/*患者的住院函数*/
void hospitalize(struct Data* newNode)//住院
{
    struct Data * p = inHospital;
    while(p)
    {
        if(newNode->ID == p->ID)
        {
            printf("该患者已经正在住院,无法重复办理住院\n");
            return;
        }
        p = p->next;
    }
    int months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    printf("请输入入院时间,格式:月 日 时如: \"9 10 10\",数字间以空格间隔 \n");
    int m,d,h,s;
    newNode->treatment.hospitalization.zhuyuanyajin = 0;
    int time1 = 0;
    for(;;)
    {
        scanInt(&m, 2);
        scanInt(&d, 2);
        scanInt(&h, 2);
        s = 0;
        if((m > 0)&&(m < 13)&&(d > 0)&& (d <= months[m])&&(h >= 0)&&(h < 24)&&(s >= 0)&&(s < 60))
        {

        }
        else
        {
            printf("请检查输入格式重新输入:");
            continue;
        }
    time1 = m * 1000000;
    time1 += (d * 10000);
    time1 += (h * 100);
    time_t now;
    struct tm* tm_now;
    time(&now);
    tm_now = localtime(&now);
    int tmp = (tm_now->tm_mon+1) * 1000000 + tm_now->tm_mday * 10000 + tm_now->tm_hour * 100;
    if(tmp > time1)
    {
        printf("请保证入院时间晚于当前时间\n");
        continue;
    }
    else
        break;


    }
    newNode->treatment.hospitalization.ruyuanshijian = time1;
    int m1,d1,h1;
    printf("请输入预计出院时间,格式:月 日 时如: \"9 10 10\",数字间以空格间隔 \n");
    int time2;
    for(;;)
    {
        scanInt(&m1, 2);
        scanInt(&d1, 2);
        scanInt(&h1, 2);
        if((m1 > 0)&&(m1 < 13)&&(d1 > 0)&& (d1 <= months[m])&&(h1 >= 0)&&(h1 < 24))
        {
            time2 = m1 * 1000000;
            time2 += (d1 * 10000);
            time2 += (h1 * 100);
            if(time1 < time2)
            {
            }
            else
            {
                printf("请保证出院时间晚于入院时间\n");
                continue;
            }
    time_t now;
    struct tm* tm_now;
    time(&now);
    tm_now = localtime(&now);
    int tmp = (tm_now->tm_mon+1) * 1000000 + tm_now->tm_mday * 10000 + tm_now->tm_hour;
    if(tmp > time2)
    {
        printf("请保证出院时间晚于当前时间\n");
        continue;
    }
    break;
        }
        else
        {
            printf("请检查输入格式\n请重新输入出院时间:");
        }
    }

    newNode->treatment.hospitalization.chuyuanshijian = time2;
    int money = timeSpan(newNode->treatment.hospitalization.ruyuanshijian,newNode->treatment.hospitalization.chuyuanshijian) * 200;

    for(;;)
    {
         printf("请缴纳押金 至少为 %d元,至多为99900元,且必须为100的整数倍\n", money+1000);
         scanInt(&(newNode->treatment.hospitalization.zhuyuanyajin),7);
         if(((newNode->treatment.hospitalization.zhuyuanyajin) < money+1000) ||(newNode->treatment.hospitalization.zhuyuanyajin > 99999)||(newNode->treatment.hospitalization.zhuyuanyajin%100))
            printf("非法输入\n");
         else
            break;
    }
    printf("已缴纳!\n");
    struct Data* node_hospital = (struct Data*)malloc(sizeof(struct Data));
    node_hospital->next = NULL;
    if(inHospital == NULL)
        {
            inHospital = node_hospital;
            inHospitalRear = node_hospital;
        }
    else
        {
            inHospitalRear->next = node_hospital;
            inHospitalRear =  node_hospital;
        }
    node_hospital->age = newNode->age;
    node_hospital->ID = newNode->ID;
    node_hospital->number = newNode->number;
    strcpy(node_hospital->name,newNode->name);
    node_hospital->treatment.hospitalization.chuyuanshijian = newNode->treatment.hospitalization.chuyuanshijian;
    node_hospital->treatment.hospitalization.ruyuanshijian = newNode->treatment.hospitalization.ruyuanshijian;
    node_hospital->treatment.hospitalization.zhuyuanyajin = newNode->treatment.hospitalization.zhuyuanyajin;
    node_hospital->treatment.exminationFee.next = NULL;
    node_hospital->treatment.medicine.next = NULL;
    return;
}




/*患者进行检查的函数*/
void selectExaminations(struct Data * newnode)
{
    char s[20];
    struct ExaminationFee *p1 = &(newnode->treatment.exminationFee),*p2;
    struct ExaminationFee * container[200];
    int command;
    for(;;)
    {
        int flag = 0;
        printf("请输入检查项目名,输入exit退出界面\n");
        scanStr(s,10);
        if(s[0]=='e')
            break;
        if(strlen(s) < 3)
        {
            printf("检索关键词过短");
            continue;
        }
        struct ExaminationFee *p = examlists;
        int itr = 0;
        printf("\n\n\n");
        while(p)
        {
            if(compStr(s,strlen(s),p->name,strlen(p->name)))
            {
                container[itr++] = p;
                flag = 1;
                printMargin(5);
                printf("%d 、%s 单价: %d元 %d角\n\n",itr,p->name, p->cost/10, p->cost % 10);
            }
            p = p->next;
        }
        if(!flag)
            {
                printf("未找到匹配的检查项目,请重新输入\n");
                continue;
            }
            for(;;)
        {
            printf("请选择检查项目的序号,选择0则重新检索:");
            scanInt(&command, 3);
            if((command < 0) ||(command > itr))
            {
                printf("输入非法!\n");
            }
            else
                break;

        }
        if(command == 0)
            continue;
        p = container[command - 1];
       printf("%s 已选择√\n",p->name);
        newnode->treatment.totalExaminationFee += p->cost;

        p2 = (struct ExaminationFee*) malloc (sizeof(struct ExaminationFee));
        p2->cost = p->cost;
        strcpy(p2->name,p->name);
        p2->next = NULL;
        p1->next = p2;
        p1 = p2;
        printf("继续选择请选择1,结束选择请选择0\n");
        for(;;)
        {
            scanInt(&command, 2);
            if((command <0)||(command > 1))
                {
                    printf("输入非法!\n");
                }
            else
                break;
        }
        if(command == 0)
            break;
    }

    printExamList(&(newnode->treatment.exminationFee));
    return;
}

/*主菜单*/
void menu()
{
    int (*mainMenu[5])() = {registe,inpatientDapart,dataViewMenu,dataChangeMenu};
    int command = 0;
    while(1)
    {
        system("cls");
        printf("\n\n\n\n\n\n\n");
        printMargin(40); printf("|----------主菜单----------|\n");
        printMargin(40); printf("|                          |\n");
        printMargin(40); printf("|");printMargin(8); printf("1、挂号");printMargin(11);printf("|\n");
        printMargin(40); printf("|                          |\n");
        printMargin(40); printf("|");printMargin(8); printf("2、住院部");printMargin(9);printf("|\n");
        printMargin(40); printf("|                          |\n");
        printMargin(40); printf("|");printMargin(8); printf("3、浏览数据");printMargin(7);printf("|\n");
        printMargin(40); printf("|                          |\n");
        printMargin(40); printf("|");printMargin(8); printf("4、修改数据");printMargin(7);printf("|\n");
        printMargin(40); printf("|                          |\n");
        printMargin(40); printf("|");printMargin(8); printf("0、退出系统");printMargin(7);printf("|\n");
        printMargin(40); printf("|                          |\n");
        printMargin(40); printf("|--------------------------|\n\n\n\n\n\n\n");
        printf("请选择:");
        scanInt(&command,1);
        if((command > 4)||(command<0))
        {
            printf("请检查输入!\n");
            continue;
        }
        if(!command)
            break;
        system("cls");
        mainMenu[command-1]();
    }
}
/*从文件中加载医院所有的检查项目*/
void inputExamData()
{
    FILE *pf_exa = fopen("hospital/examination.txt","r");

    examlists = (struct ExaminationFee *)malloc(sizeof(struct ExaminationFee));
    struct ExaminationFee * p = examlists,*p1;
    while(!feof(pf_exa))
    {
        p1 = (struct ExaminationFee *)malloc(sizeof(struct ExaminationFee));
        int tmp;
        fscanf(pf_exa,"%d%s%d",&tmp,p1->name,&(p1->cost));
        p1->next = NULL;
        p->next = p1;
        p = p1;
    }
    fclose(pf_exa);
}


int clearExamList()
{
    struct ExaminationFee * p, *p1;
    p = examlists;
    while(p)
    {
        p1 = p;
        p = p->next;
        free(p1);
    }
    return 0;
}

void openUTDfile()//打开最新的数据文件
{
    time_t timep;
    time(&timep);
    char location[20] = "data/";
    strftime(location+5,sizeof(location),"%m%d",localtime(&timep));
    location[9] = '/';
    location[10] = 0;
    dataHead = input(location);
    return;
}



int scanInt(int *num,int length)//输入整型变量,回车键或空格键结束输入,非法字符会被忽略,过长输入会被截取,输入过长返回-1;
{
    *num = 0;
    char c = getchar();
    int len = 0;
    while((c > '9')||(c < '0'))
    {
        c = getchar();
    }
    while((c != '\n') && (c != ' '))
    {
        if((c <= '9')&& (c >= '0'))
        {
            *num *= 10;
            *num += (c - '0');
            ++len;
            if(len >= length)
            {
                c = getchar();
                if(c == '\n')
                    return len;
                while((c != '\n') && (c != ' '))
                {
                    c = getchar();
                }
                return -1;
            }
        }
        c = getchar();
    }
    return len;
}
int scanName(char *s,int length)//输入姓名,返回-1为输入过长,非法字符会被过滤
{

    char c = getchar();
    while(!((c < 0)||((c <= 'Z')&&(c >= 'A'))||((c <= 'z')&&(c >= 'a'))))
    {
        c = getchar();
    }
    s[0] = c;
    int i = 0;
    if(c < 0)//中文
    {
        while(c != '\n')
    {
        c = getchar();

        if(c >= 0)
            continue;
        s[++i] = c;
        if(i >= length-1)
        {
            s[++i] = 0;
                while(c != '\n')
                {
                c = getchar();
                }
                return -1;
        }
    }
    }
    else
    {
        while(c != '\n')
        {
            c = getchar();
            if(!(((c <= 'Z')&&(c >= 'A'))||((c <= 'z')&&(c >= 'a'))||(c == ' ')))
                continue;
            s[++i] = c;
            if(i >= length-1)
            {
                s[++i] = 0;
                while(c != '\n')
                {
                c = getchar();
                }
                return -1;
            }
        }
    }
    s[++i] = 0;
    return i;
}
int scanStrNum(char *num,int length)//输入数字的字符串,回车结束输入,其他非数字的字符会被过滤,返回值为长度,长度过长返回-1.
{
    char c = getchar();
    int i = 0;
    while((c > '9') || (c < '0'))
    {
        c = getchar();
    }
    while(c != '\n')
    {
        if((c <= '9')&&(c >= '0'))
        {
        num[i++] = c;
        if(i >= length)
        {
            num[i] = 0;
            while(c != '\n')
            {
            c = getchar();
            }
            return -1;
        }
        }
        c = getchar();
    }
    num[i] = 0;
    return (i-1);
}

void saveHosData()
{
    FILE *pf = fopen("hospital/hospital.txt","w");
    struct Data * p = inHospital;
    while(p)
    {
        int sex = (p->number % 100000) / 10000;
        fprintf(pf,"%08d %20s %d %03d %08d ",p->ID,p->name,sex ,p->age,p->treatment.hospitalization.ruyuanshijian);
        fprintf(pf,"%08d %08d\n",p->treatment.hospitalization.chuyuanshijian,p->treatment.hospitalization.zhuyuanyajin);
        p = p->next;
    }
    fclose(pf);
}

/*加载住院数据*/
void loadHospitalizeData()
{
    inHospital = NULL;
    inHospitalRear = NULL;
    FILE *pf = fopen("hospital/hospital.txt","r");
    if(!pf)
        return;
    inHospital = (struct Data*)malloc(sizeof(struct Data));
    inHospital->treatment.medicine.next = NULL;
    inHospital->treatment.exminationFee.next = NULL;
    struct Data *p = inHospital, *p1;
    p->next = NULL;
    while(!feof(pf))
    {
            int sex;
            p1 = p;
            p->next = (struct Data*)malloc(sizeof(struct Data));
            p = p->next;
            p->next = NULL;
            p->treatment.medicine.next = NULL;
            p->treatment.exminationFee.next = NULL;
            fscanf(pf,"%d%s%d%d%d",&(p->ID),p->name,&sex,&(p->age),&(p->treatment.hospitalization.ruyuanshijian));
            fscanf(pf,"%d%d",&(p->treatment.hospitalization.chuyuanshijian),&(p->treatment.hospitalization.zhuyuanyajin));
            p->number = sex * 10000;
    }
    inHospitalRear = p1;
    p1->next = NULL;
    free(p);
    p = inHospital;
    inHospital = p->next;
    free(p);
    fclose(pf);
}


void countAllDoc()//统计所有医生的繁忙情况
{
    openUTDfile();
    extern int countDepartment[7];
    extern struct Doctor doctor_departments[5];
    extern struct Data*  dataHead;
    for(int i = 0; i < 5; ++i)
    {
    countDepartment[i] = 0;
    struct Doctor *p_doc = doctor_departments[i].next;
    while(p_doc)
    {
        struct Data * p_data = dataHead->next;
        p_doc->registed = 0;
        while(p_data)
        {
            if(p_data->doctor.number == p_doc->number)
            {
                ++(p_doc->registed);
                ++countDepartment[i];
            }
            p_data = p_data->next;
        }

        p_doc = p_doc->next;
    }

    }
    return;
}



int showDepartStatus()//繁忙情况统计的交互界面
{
    countAllDoc();
    w_countAllDoc();
    system("cls");
    extern struct Doctor doctor_departments[5];
    extern char departments[7][20];
    printf("要查看哪个科室的情况? 输入0返回上一层\n");
    for(int i = 0; i < 5; ++i)
    {
        printMargin(40);
        printf("%d、%s\n\n",i+1,departments[i]);
    }
    printf("请选择:");
    int command;
    for(;;)
    {
        scanInt(&command,3);
        if((command < 0)||(command > 5))
        {
            printf("输入非法\n");
        }
        else
            break;
    }
    system("cls");
    printMargin(40);
    printf("%s 所有医生挂号状况如下:\n\n\n",departments[command-1]);
    printMargin(40);
    printf("该科室今天共有%d个病人\n",countDepartment[command-1]);
    showDocRegisted(doctor_departments[command-1].next);

    printMargin(40);printf("按任意键返回上一层");
    getchar();
    return 0;
}

void showDocRegisted(struct Doctor *head)//以科室头指针为参数,显示该科室医生的繁忙情况
{
    char dic[7][3] = {"日","一","二","三","四","五","六"};
    struct Doctor * p_doc = head;
    int counter = 0;
    while(p_doc)
    {
        int workDay = 0;
        printMargin(40);
        printf("%d %10s 今天共有%2d病人 本周共有%d病人\n",++counter,p_doc->name,p_doc->registed,p_doc->w_registed);
        printMargin(40);printf("上班时间: 周");
            for(int i = 0; i < 7; ++i)
        {
            if(p_doc->workingHours[i])
                {
                    printf("%s、",dic[i]);
                    ++workDay;
                }
        }
        printf("\n");
        printMargin(40);
        printf("今天挂号率:%.2f%% 本周挂号率: %.2f%%\n\n",(float)(p_doc->registed)*10, (float)(p_doc->w_registed*10/workDay));
        p_doc = p_doc->next;
    }
    return;
}
int leaveHospital(struct Data *p)
{

    time_t now;
    struct tm* tm_now;
    time(&now);
    tm_now = localtime(&now);
    int tmp = (tm_now->tm_mon+1) * 1000000 + tm_now->tm_mday * 10000 + tm_now->tm_hour;
    extern struct Data* inHospital;
    int hos_time = timeSpan(p->treatment.hospitalization.ruyuanshijian,tmp);
    int hos_money = 200 * hos_time;
    printf("您共住院%d天,产生住院费%d元 住院押金剩余%d",hos_time,hos_money,p->treatment.hospitalization.zhuyuanyajin-hos_money );
    if(p->treatment.hospitalization.zhuyuanyajin-hos_money >= 0)
         printf("余额已返还,请确认\n");
     else
      {
        printf("请缴纳欠款!\n");
    }
    FILE *pf_money = fopen("data/money.txt","r+");
    fseek(pf_money,0,SEEK_SET);
    int money;
    fscanf(pf_money,"%d",&money);
    if(p->treatment.hospitalization.zhuyuanyajin-hos_money >= 0)
    money = money - p->treatment.hospitalization.zhuyuanyajin + hos_money;
    else
        money = money + p->treatment.hospitalization.zhuyuanyajin - hos_money;
    fseek(pf_money,0,SEEK_SET);
    fprintf(pf_money,"%d",money);
    fclose(pf_money);
    printfMoneyStatus();
    printf("出院成功!\n\n\n\n\n\n");
    printf("按任意键返回主菜单\n");
    getchar();
    system("cls");
    printf("\n\n\n\n\n");
    printMargin(40);
    printf("出院成功!\n\n\n\n\n\n");
    printf("按任意键返回主菜单\n");
    getchar();
    return 0;
}


int patientAdminMenu()
{
    struct Data* p = inHospital;
    struct Data * p1 = p;
    printf("请输入病人ID,输入0返回上一层\n");
    int id;
    for(;;)
    {
        int length = scanInt(&id, 9);
        if(!id)
            return 0;
        if(length != 8)
        {
            printf("输入非法!请重新输入:");
            continue;
        }
        while(p)
        {
            if(p->ID == id)
                break;
            p1 = p;
            p = p->next;
        }
        if(p == NULL)
            printf("未找到该患者\n");
        else
            break;

    }
    system("cls");
    showPatientsInfo(p);
    printf("\n\n\n");
    printMargin(40);
    printf("1、办理出院\n\n");
        printMargin(40);
    printf("2、延迟出院\n\n");
        printMargin(40);
    printf("0、退出系统\n\n\n\n\n\n\n\n\n");
        printMargin(40);
    printf("请选择:");
    int command;
    for(;;)
    {
        scanInt(&command,3);
        if((command < 0)|| (command > 2))
            printf("输入非法");
        else
            break;
    }
    switch(command)
    {
        case 1:
            {
                leaveHospital(p);
                if(p == inHospital)
                inHospital = p->next;
                else
                    p1->next = p->next;
                free(p);
                break;
            }
        case 2: delayTime(p); break;
        case 0: break;
    }
    return 0;
}

int delayTime(struct Data *p)
{
    int b;
    int money = 0;
    while(1)
    {
    int a = p->treatment.hospitalization.chuyuanshijian;

    int t[3];
    printf("请输入月 日 时中间用空格分隔,如:9 2 1 :");
    scanInt(&(t[0]),2);
    scanInt(&(t[1]),2);
    scanInt(&(t[2]),2);
    b = t[0] * 1000000 + t[1] * 10000 + t[2] * 100;

    if(timeSpan(a,b) != 0)
        {
        int cost = timeSpan(p->treatment.hospitalization.ruyuanshijian,b) * 200;
        if(cost+1000 > p->treatment.hospitalization.zhuyuanyajin)
        printf("请续缴住院费,至少缴纳%d 元,至多缴纳99999元",cost+1000 - p->treatment.hospitalization.zhuyuanyajin);
        else
            break;
        for(;;)
        {
            scanInt(&money, 7);
            if((money < cost+1000 - p->treatment.hospitalization.zhuyuanyajin)||(money > 99999))
            printf("请检查输入!\n");
            else
                break;
        }

        break;
    }
   printf("输入不合法,请检查\n");
    }

       printf("操作成功! 任意键返回上一级\n");
       getchar();
    FILE *pf_money = fopen("data/money.txt","r+");
    int money_;
    fseek(pf_money,0,SEEK_SET);
    fscanf(pf_money,"%d",&money_);
    money_ = money + money_;
    fseek(pf_money,0,SEEK_SET);
    fprintf(pf_money,"%d",money_);
    fclose(pf_money);
    p->treatment.hospitalization.chuyuanshijian = b;
        printfMoneyStatus();
               printf("操作成功! 任意键返回上一级\n");
       getchar();
    return 0;
}

int timeSpan(int start, int end)//日期不合法返回0
{
    int a = start / 100;
    int b = end / 100;
    if(end <= start)
        return 0;
    int months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    int m1,d1,h1,m2,d2,h2;
    h1 = a % 100;
    a /= 100;
    d1 = a % 100;
    a /= 100;
    m1 = a;
    h2 = b % 100;
    b /= 100;
    d2 = b % 100;
    b /= 100;
    m2 = b;
    if((m1<1)||(m1>12)||(m2<1)||(m2>12))
        return -1;
    if((d1<1)||(d1>months[m1])||(d2<1)||(d2>months[m2]))
        return -1;
    if((h1<0)||(h1>23)||(h2<0)||(h2>23))
        return -1;
    int sum = 0;
    for(int i = m1; i < m2; ++i)
        sum += months[i];
    sum += d2;
    sum -= d1;
    if(h2 > 8)
        ++sum;
    return sum;
}

int printfMoneyStatus()
{
    FILE *pf_money = fopen("data/money.txt","r");
    int money;
    fscanf(pf_money,"%d",&money);
    printf("\n\n\n\n\n\n\n");
    printMargin(40);
    printf("当前医院总营业额为%d元%d角\n\n\n\n\n\n",money/10,money%10);
    fclose(pf_money);
    return 0;
}

int inputDate(int *month, int *day)//输入月、日,并检查格式
{
    int months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    printf("请输入月 日 中间用空格隔开");

    for(;;)
    {
        scanInt(month,9);
        if((*month > 12)||(*month <0))
        {
            printf("输入不正确,请检查\n");
        }
        else
            break;
    }
    for(;;)
    {
        scanInt(day,9);
        if((*day < 0) || (*day > months[*month]) )
        {
            printf("输入不正确,请检查\n");
        }
        else
            break;
    }
    return 0;
}


struct Data* reInput(const char* dir)//打开以路径“dir”为参数的所有文件,路径格式:“data/1001/”,并逆序建立链表。
{
    FILE *pf, *pf_med, *pf_exam;
    char position[40];
    strcpy(position,dir);
    strcpy(position+10,"data.txt");
    sequence = 0;
    struct Data *  base =  (struct Data*)malloc(sizeof(struct Data));
	base->next = NULL;
    if(pf = fopen(position,"r"),pf==NULL)
    {

        dataRear = base;
        dataHead = base;
        return base;
    }
    strcpy(position+10,"examination.txt");
    pf_exam = fopen(position,"r");
    strcpy(position+10,"medicine.txt");
	pf_med = fopen(position,"r");
	struct Data *p1, *p2 = NULL;
	p1 = base;

	int itr = 1;
	int flag = 0;
	fseek(pf,-123,SEEK_END);
	while(!flag)
	{
	    int countScan = 0;
		p2 = (struct Data *)malloc(sizeof(struct Data));
		p2->next = NULL;
		p1->next = p2;
		countScan = fscanf(pf,"%d%d%s%d%d%s",&(p2->number),&(p2->ID),p2->name,&(p2->age),&(p2->doctor.number),p2->doctor.name);
		if(countScan != 6)
        {
            reSeek(pf);
            continue;
        }
		countScan = fscanf(pf,"%d%d",&p2->doctor.level,&p2->doctor.department);
        if(countScan != 2)
        {
            reSeek(pf);
            continue;
        }
        countScan = 0;
		int i;
		for(i = 0; i < 7; ++i)
		countScan += fscanf(pf,"%d",&(p2->doctor.workingHours[i]));
        if(countScan != 7)
        {
            reSeek(pf);
            continue;
        }
		if(fscanf(pf,"%d",&(p2->treatment.total))!=  1)
        {
            reSeek(pf);
            continue;
        }
		int med_start,med_end,exam_start,exam_end;
		countScan = fscanf(pf,"%d%d%d%d",&med_start,&med_end,&exam_start,&exam_end);
		if(countScan != 4)
        {
            reSeek(pf);
            continue;
        }
		countScan = fscanf(pf,"%d%d",&(p2->treatment.hospitalization.ruyuanshijian),&(p2->treatment.hospitalization.chuyuanshijian));
		if(countScan != 2)
        {
            reSeek(pf);
            continue;
        }
		p2->treatment.medicine.next = NULL;

		fgetc(pf);
		p2->treatment.totalMedicineCharge = buildMedList(&(p2->treatment.medicine),pf_med,med_start,med_end);
		p2->treatment.totalExaminationFee = buildExamList(&(p2->treatment.exminationFee), pf_exam,exam_start,exam_end);
		p1 = p2;
		flag = fseek(pf,-(++itr) * 123,SEEK_END);
	}
	dataRear = p1;
	fclose(pf);
	fclose(pf_exam);
	fclose(pf_med);
	return base;

}

int viewUTDdata(int n)//打开最新的数据文件
{
    system("cls");
    extern char departments[7][20];
    extern struct Data* dataHead;

    struct Data* dataHeadToDel[100];
    int i_del = 0;
    if(n > 100)
    {
        printf("最多查看100条数据\n");
        return -1;
    }
    time_t timep;
    time(&timep);
    char location[20] = "data/";
    strftime(location+5,sizeof(location),"%m%d",localtime(&timep));
    location[9] = '/';
    location[10] = 0;
    int count = 0;
    struct Data *container[120];

    while(count < n)
    {
    dataHead = reInput(location);
    struct Data *p = dataHead->next;
    if(!p)
    {
        free(dataHead);
    }
    else
    {
        dataHeadToDel[i_del++] = dataHead;
    }
    printf("数据日期:%c%c月%c%c日:\n",location[5],location[6],location[7],location[8]);
    while(p)
    {
        container[count] = p;
        printf("---------------------\n");
        printf("%d、  ",++count);
        printf("序号:%d 患者姓名:%s ID:%d 患者年龄: %d  ", p->number, p->name,p->ID, p->age);
        printf("主治医生:%s %s %s 工号:%d \n药品费: %d元%d角\n",departments[p->doctor.department],DoctorLevel[p->doctor.level],p->doctor.name,p->doctor.number,(p->treatment.totalMedicineCharge)/10,(p->treatment.totalMedicineCharge)%10);
        printMedList(&(p->treatment.medicine));
        printf("检查费: %d元 %d角",(p->treatment.totalExaminationFee)/10,(p->treatment.totalExaminationFee)%10);
        printExamList(&(p->treatment.exminationFee));
        printf("\n\n\n\n");
        p = p->next;
        if(count >= n)
            break;
    }

        preDay(location);
    }
    container[count] = NULL;

    for(;;)
    {printMargin(40);
    printf("1:按医生筛选数据\n");
     printMargin(40);
    printf("2:按患者ID筛选数据\n");
     printMargin(40);
    printf("3:按科室筛选数据\n");
     printMargin(40);
    printf("0: 退出\n");
    int command;
    for(;;)
    {
        printf("请选择:");
        scanInt(&command,3);
        if((command <0)||(command > 3))
        {
            printf("输入不合法\n");
        }
        else
            break;
    }
    switch(command)
    {
    case 1:
        {
            int id;
            printf("请输入医生ID(8位):");
            for(;;)
            {
                if(scanInt(&id,9) != 8)
                {
                    printf("数据非法!请重新输入\n");
                }
                else
                    break;
            }
            viewByDoctorID(container,id);
            break;
        }
    case 2:
        {
            int id;
            printf("请输入患者ID(8位):");
            for(;;)
            {
                if(scanInt(&id,9) != 8)
                {
                    printf("数据非法!请重新输入\n");
                }
                else
                    break;
            }
            viewByPatientID(container,id);
            break;
        }
    case 3:
        {
            int nn;
            for(int i = 0; i < 5; ++i)
            printf("%d、%s\n",i+1,departments[i]);
            printf("请选择:");
            for(;;)
            {
                scanInt(&nn,3);
                if((nn < 1)||(nn > 5))
                {
                    printf("输入非法\n");
                }
                else
                    break;
            }
            viewByDepart(container,nn-1);
            break;
        }
        case 0:break;
    }
    if(!command)
        break;
    }

    for(int i = 0; i < i_del; ++i)
        clearList(dataHeadToDel[i]);
    return 0;
}



void w_countAllDoc()//统计所有医生本周的繁忙情况
{
    extern struct Doctor doctor_departments[5];
    struct Doctor * p_doc;
    int count_w = 0;
    time_t timep;
    time(&timep);
    char location[20] = "data/";
    strftime(location+5,sizeof(location),"%m%d",localtime(&timep));
    location[9] = '/';
    location[10] = 0;
    dataHead = input(location);

    for(int i = 0; i < 5; ++i)
    {
        p_doc = doctor_departments[i].next;
        while(p_doc)
        {
            p_doc->w_registed = 0;
            p_doc = p_doc->next;
        }
    }


    while(count_w < 7)//打开7天的数据
    {
        if(dataHead->next)//导入成功
        {
            ++count_w;
            for(int i = 0; i < 5; ++i)
            {
                p_doc = doctor_departments[i].next;

                while(p_doc)
                {
                    struct Data * p = dataHead->next;
                    while(p)
                    {
                        if(p->doctor.number == p_doc->number)
                        {
                            ++(p_doc->w_registed);
                        }
                        p = p->next;
                    }
                    p_doc = p_doc->next;
                }
            }
        }
        preDay(location);
        clearList(dataHead);
        dataHead = input(location);
    }
}

int showPatientsInHospital()
{
    system("cls");
    printf("当前住院患者如下:\n\n");
    struct Data *p = inHospital;
    int count = 0;
    while(p)
    {
        ++count;
        printf("------------------------------------------------------------\n");
        printf("%d、 ",count);
        showPatientsInfo(p);
        printf("\n------------------------------------------------------------\n");
        printf("\n\n");
        p = p->next;
    }
    printf("按任意键返回上一级\n");
    getchar();
    return 0;
}


int scanStr(char *s, int length)
{
    int count = 0;
            char c;
    while(count < length)
    {

        c = getchar();
        if(c == '\n')
            break;
        s[count++] = c;
    }
    s[count] = 0;
    while(c != '\n')
    {
        c  = getchar();
        ++count;
    }
    return count;
}
int dataChangeMenu()
{
    printMargin(40);
    printf("执行敏感操作,需要您输入密码\n");
    printf("\n\n\n\n\n\n\n\n\n");
    char pass[20];
    char* key = deCode();
    for(;;)
    {

        printf("请输入密码,若要退出系统请直接按回车:");
        int length = scanStr(pass,15);
        if(length == 0)
            return 0;
        if(strcmp(pass,key))
        {
            printf("密码错误!\n");
        }
        else
        {
            printf("密码正确,正在载入\n");
            loading();
            system("cls");
            break;
        }
    }
    free(key);
    for(;;)
    {printf("\n\n\n\n\n\n\n");
    printMargin(40);
    printf("1、诊断记录修改\n\n");
        printMargin(40);
    printf("2、密码修改\n\n");
        printMargin(40);
    printf("0、返回主菜单\n\n\n\n\n\n\n\n");

    int command;
    for(;;)
    {
        printf("请选择序号:");
        scanInt(&command,3);
        if((command > 2)||(command < 0))
        {
            printf("输入非法!\n");
        }
        else
            break;
    }
    if(command == 0)
        return 0;
    if(command == 1)
    {
        changeDataMenu();
    }
    else if (command == 2)
    {
        printf("请设置新密码\n");
        setPassWord();
    }
    else
    {
        printf("系统构建中\n\n");
        printf("按任意键返回主菜单\n\n");
        getchar();
    }
    }
    return 0;

}



int changeDoctorData(struct Doctor *p)
{
    extern char departments[7][20];
    extern const char DoctorLevel[5][12];
    int command;
      for(;;)
    {
        printf("请选择需要修改哪一项:\n");
        printf("1、医生姓名 2、 医生职级 3、医生科室\n");
        scanInt(&command, 2);
        if((command < 1)||(command > 3))
        {
            printf("输入不合法,请检查 \n");
        }
        else
            break;

    }
    switch(command)
    {
    case 2:
        {
            printf("请选择修改后的医生职级(输入序号):");
            printf("1:%s\n2:%s\n3:%s\n4:%s\n",DoctorLevel[1],DoctorLevel[2],DoctorLevel[3],DoctorLevel[4]);
            for(;;)
            {
                int n;
                scanInt(&n,4);
                if((n < 1)||(n > 4))
                    printf("输入不合法!\n");
                else
                {
                    p->level = n;
                    break;
                }

            }
            break;
        }
    case 1:
        {
            printf("修改姓名:");
            scanName(p->name,20);
            break;
        }
    case 3:
        {
            printf("修改科室(输入序号):");
            printf("1:%s\n2:%s\n3:%s\n4:%s\n5:%s\n\n",departments[0],departments[1],departments[2],departments[3],departments[4]);
            for(;;)
            {
                int n;
                scanInt(&n,4);
                if((n < 1)||(n > 5))
                    printf("输入不合法!\n");
                else
                {
                    p->department = n-1;
                    break;
                }

            }
            break;

        }
    }
    printf("修改成功!修改后的医生信息为:");
    printf("%s %s %s \n",departments[p->department],DoctorLevel[p->level],p->name);

    return 0;

}


int changeExamList(struct ExaminationFee * head)
{
    struct ExaminationFee *p = head->next;
    struct ExaminationFee * line[200];
    int i = 0;
    while(p)
    {
        line[i] = p;
        printf("%d)、  项目名: %15s 单价:%5d \n",++i,p->name,p->cost);
        p = p->next;
    }
    line[i] = NULL;
        int command;
        for(;;)
        {
            printf("请选择需要执行的操作:1、增加一条数据 2、删除一条数据 3、修改数据\n");
            scanInt(&command,3);
            if((command >3) || (command < 1))
            {
                printf("输入不合法\n");
            }
            else
                break;
        }
        switch (command)
        {
        case 1://插入一条数据
            {
                struct ExaminationFee * pnew = (struct ExaminationFee *) malloc (sizeof(struct ExaminationFee));
                pnew->next = NULL;
                printf("请输入检查项目名称:");
                scanStr(pnew->name,14);
                for(;;)
                {
                    printf("请输入检查项目价格(格式: 元 角,最高不超过99999元) 中间用空格隔开:");
                    int m, n;
                    for(;;)
                    {
                        scanInt(&m, 6);
                        scanInt(&n,3);
                        if((m < 0)||(m > 99999)||(n < 0)||(n > 9))
                        {
                            printf("请检查输入格式\n");
                        }
                        else
                        {
                            pnew->cost = m * 10 + n;
                            break;
                        }
                    }
                }

                break;
            }
        case 2://删除一条数据
            {
                if(!i)//链表为空
                {
                    printf("没有可删除的数据\n");
                    break;
                }
                printf("请输入欲删除的数据序号\n");
                for(;;)
                {
                    int command;
                    scanInt(&command,3);
                    if((command < 0)||(command > i))
                    {
                        printf("请检查输入格式!\n");
                    }
                    else
                    {
                        if(command == 1)
                        {
                            free(line[0]);
                            head->next = NULL;
                        }
                        else
                        {
                            free(line[command - 1]);
                            line[command - 2]->next = line[command];
                        }
                        printf("已删除");
                        break;
                    }
                }

                break;
            }

        case 3://修改一条数据
            {
                int command;
                struct ExaminationFee *pp;
                for(;;)
                {
                    printf("请输入欲修改的数据序号:");
                    scanInt( &command, 3);
                    if((command > i)||(command < 0))
                    {
                      printf("输入不合法!\n");
                    }
                    else
                    {
                        pp = line[command - 1];
                        break;
                    }
                }
                printf("请输入检查项目名称:");
                scanStr(pp->name,14);
                for(;;)
                {
                    printf("请输入检查项目价格(格式: 元 角,最高不超过99999元) 中间用空格隔开:");
                    int m, n;
                    for(;;)
                    {
                        scanInt(&m, 6);
                        scanInt(&n,3);
                        if((m < 0)||(m > 99999)||(n < 0)||(n > 9))
                        {
                            printf("请检查输入格式\n");
                        }
                        else
                        {
                            pp->cost = m * 10 + n;
                            break;
                        }
                    }
                }

                break;


            }
        }
    p = head->next;
    printf("修改后数据:\n");
    i = 0;
    while(p)
    {
        line[i] = p;
        printf("%d)、  项目名: %15s 单价:%5d \n",++i,p->name,p->cost);
        p = p->next;
    }
        return 0;
}



int changeDataMenu()
{
        extern struct Data* dataHead;
        char position[20] = "data/";
        int start_m, start_d;
        system("cls");
        printf("\n\n\n\n\n\n");
        printf("要修改哪天的数据呢?\n");
        inputDate(&start_m,&start_d);
        position[5] = start_m / 10 + '0';
        position[6] = start_m % 10 + '0';
        position[7] = start_d / 10 + '0';
        position[8] = start_d % 10 + '0';
        position[9] = '/';
        position[10] = 0;
        dataHead = input(position);
        if(changeData() == -1)
        {
            printf("\n\n\n\n\n\n\n");
            printMargin(40);
            printf("未找到这一天的数据,按任意键返回上一层\n");
            getchar();
            system("cls");
        }
        saveData(position);
        clearList(dataHead);
    return 0;
}
int setPassWord()//加密控件
{
    char key[21];
    int length;
    for(;;)
    {
        printf("请输入新密码(8到16位):");
        length = scanStr(key,17);
        if((length > 16)||(length < 8))
           {
               printf("请检查输入长度\n");
               continue;
           }
        printf("请再次输入:");
        char key2[20];
        scanStr(key2,18);
        if(strcmp(key,key2))
        {
            printf("两次输入密码不一致,请检查\n");
            continue;
        }
        break;
    }
    srand(time(0));
    FILE *pf = fopen("data/key.txt","wb");
    for(int i = 0; i < length; ++i)
    {
        for(int j = 0; j < 7; ++j)
        {
            int num = rand()%128;
            int bi = 1 << j;
            if(((key[i]) & bi))
            {
                num |= bi;
            }
            else
                num &= (~bi);
            fwrite(&num,1,1,pf);
        }
    }
    fclose(pf);
    return 0;
}

char * deCode()
{

    FILE *pf = fopen("data/key.txt","rb");
    char *password = (char *)malloc(20);
    int pos = 0;
    int num;
    while(!feof(pf))
    {
        num = 0;
        for(int i = 0; i < 7; ++i)
        {
            int tmp;
            int bi = (1 << i);
            fread(&tmp,1,1,pf);
            num += (tmp & bi);
        }
        password[pos++] = num;

    }
    password[pos-1] = 0;
    fclose(pf);
    return password;
}



int dataViewMenu()
{
    printf("\n\n\n\n\n");
    printMargin(40);printf("1、医生信息\n\n");
    printMargin(40);printf("2、营业额 \n\n");
    printMargin(40);printf("3、诊疗记录浏览 \n\n");
    printMargin(40);printf("0、返回上一层\n\n\n\n\n");
    int command;
    for(;;)
    {
        printf("请选择一项(输入序号):");
        scanInt(&command,3);
        if((command > 3)||(command < 0))
        {
            printf("输入非法\n");
        }
        else
            break;
    }
    switch(command)
    {
        case 1: showDepartStatus(); break;
        case 2:
            {
                system("cls");
                printfMoneyStatus();
                printf("按任意键返回\n");
                getchar();
                break;
            }
        case 3: viewData();break;
        case 0: break;
    }
    return 0;
}

int inpatientDapart()
{
    for(;;)
    {
        system("cls");
        printf("\n\n\n\n\n");
    printMargin(40);
    printf("1、病房信息\n\n");
        printMargin(40);
    printf("2、住院病人管理\n\n");
            printMargin(40);
    printf("0、返回主菜单\n\n\n\n\n\n\n\n\n");
    int command = 0;
    for(;;)
    {
        scanInt(&command, 3);
        if((command < 0)||(command > 3))
            printf("输入不合法\n");
        else
            break;
    }
    if(command == 1)
    {
        showPatientsInHospital();
    }
    else if(command == 2)
        patientAdminMenu();
    else
        break;
    }
    return 0;
}


int  printMargin(int n) {
    for (int i = 0; i < n; i++)
        printf(" ");
    return 0;
}

void loading() {
    system("color f0");
    int i, j;
    printf("\n\n\n\n\n\n\n\n\n\n\n\n");
    for (i = 1; i <= 10; i++)
    {
        printf("\t\t\t\t\t\t欢迎使用|");
        for (j = 0; j < i; j++)
           printf("-");
        printf("|'%d%%'\r", i*10);
        Sleep(50);
    }
    system("cls");
}

int countPatient(int id, int departmentID)//根据病人id,统计它在某个科室挂了多少号
{
    extern struct Data *dataHead;
    struct Data * p = dataHead;
    int num = 0;
    while(p)
    {
        if((p->ID == id)&&(p->doctor.department == departmentID))
        {
            ++num;
        }
        p = p->next;
    }
    return num;
}

int countPatientDoc(int id, int doctorID)//根据病人id,统计它在某个医生名下挂了多少号
{
    extern struct Data *dataHead;
    struct Data * p = dataHead;
    int num = 0;
    while(p)
    {
        if((p->ID == id)&&(p->doctor.number == doctorID))
        {
            ++num;
        }
        p = p->next;
    }
    return num;
}
int saveMedData()
{
    extern struct Medicine* mediStorage;
    struct Medicine * p = mediStorage->next;
    FILE * pf = fopen("hospital/medicine.txt","w");
    int i = 0;
    while(p)
    {
        fprintf(pf,"%06d %16s %3d %4d\n",++i,p->name,p->number,p->price);
        p = p->next;
    }
    fprintf(pf,"%8d", i);
    fclose(pf);
    return 0;
}


int reSeek(FILE *pf)
{
    char c = 0;
    while((c != '\n')&&(c != EOF))
    {
        c = fgetc(pf);
    }
    return 0;
}

//文件view.h
#ifndef HOUSJ_H_INCLUDED
#define HOUSJ_H_INCLUDED
int viewByDoctorID(struct Data ** container, int ID);//按医生工号筛选诊疗信息
int viewByDepart(struct Data ** container, int ID);//按科室筛选诊疗信息
int viewByPatientID(struct Data ** container, int ID);//按患者ID筛选诊疗信息
int countPatientDoc(int id, int doctorID);//根据病人id,统计它在某个医生名下挂了多少号
int countPatient(int id, int departmentID);//根据病人id,统计它在某个科室挂了多少号
void countAllDoc();//统计所有医生的挂号数量
void printMedList(struct Medicine * head);//输出某位患者的购药单
void printExamList(struct ExaminationFee * head);//输出某位患者的检查单
int showPatientsInHospital();//展示病房信息
int showPatientsInfo(struct Data *node);//展示住院病人的信息
int viewDataSpan();//按时间区间浏览历史诊疗记录
int printDataList(struct Data * base);//输出所建链表的所有数据
#endif // HOUSJ_H_INCLUDED
//文件view.c
#include 
#include 
#include
#include
#include 
#include 
#include 
#include
#include"basic.h"
#include"view.h"
#include"change.h"

/*打印head链表的所有的诊疗记录*/
int printDataList(struct Data * base)//返回值为链表的有效结点数
{
    if(base->next == NULL)
        return -1;
    struct Data *p = base->next;
    printf("正在打印数据...:\n\n");
    int i = 0;
    while(p)
    {
        printf("---------------------\n");
        printf("%d、  ",++i);
        printSingleData(p);
        printf("\n\n\n\n");
        p = p->next;
    }
    return i;
}

int viewByDoctorID(struct Data ** container, int ID)
{
    int itr = 0;
    int i = 0;
    int count = 0;
    while(container[itr])
    {
        if(container[itr]->doctor.number == ID)
        {
            ++i;
            printf("%d、",++count);
            printSingleData(container[itr]);
            printf("\n\n");
        }

        ++itr;
    }
        if(!i)
    {
        printMargin(40);
        printf("未找到任何数据!\n");
        printMargin(40);
        printf("按任意键返回上一层\n");
        getchar();
        return 0;
    }
    return 0;
}



int viewByDepart(struct Data ** container, int ID)
{
    int itr = 0;
    int count = 0;
    int i = 0;
    while(container[itr])
    {
        if(container[itr]->doctor.department == ID)
        {
            printf("%d、",++count);
            printSingleData(container[itr]);
            printf("\n\n");
            ++i;
        }

        ++itr;
    }
        if(!i)
    {
        printMargin(40);
        printf("未找到任何数据!\n");
        printMargin(40);
        printf("按任意键返回上一层\n");
        getchar();
        return 0;
    }
    return 0;
}



int viewByPatientID(struct Data ** container, int ID)
{
    int itr = 0;
    int count = 0;
    int i = 0;
    while(container[itr])
    {
        if(container[itr]->ID == ID)
        {
            printf("%d、",++count);
            printSingleData(container[itr]);
            printf("\n\n");
            ++i;
        }

        ++itr;
    }
        if(!i)
    {
        printMargin(40);
        printf("未找到任何数据!\n");
        printMargin(40);
        printf("按任意键返回上一层\n");
        getchar();
        return 0;
    }
    return 0;
}

/*打印购药链表*/
void printMedList(struct Medicine * head)
{
    struct Medicine *p = head->next;
    if(!p)
        return;
        printf("          ***所购药品如下:***     \n\n");
    int i = 0;
    while(p)
    {
        printf("%d)、  药品名:%s 数量:%d, 单价:%d元 %d角 \n",++i,p->name,p->number,(p->price)/10,(p->price)%10);
        p = p->next;
    }
    printf("  \n\n");
}
/*打印所做检查项目链表*/
void printExamList(struct ExaminationFee * head)
{
    struct ExaminationFee *p = head->next;
    if(!p)
        return;
    printf("\n       ***所做检查项目如下:***     \n\n");
    int i = 0;
    while(p)
    {
        printf("检查项目%d:      %s 价格:%d 元 %d 角 \n",++i,p->name,(p->cost)/10,(p->cost)%10);
        p = p->next;
    }
}
int viewDataSpan()//可以手动输入日期获取该日期的诊疗记录
{
        extern struct Data * dataHead;
        extern char departments[7][20];
        char endPosition[20] = "data/";
        char position[20] = "data/";
        int start_m, start_d;
        int end_m, end_d;
        printf("注意:您最多查看30天的数据\n");
        for(;;)
        {
            printf("请输入需要查看的起始日期\n");
            inputDate(&start_m,&start_d);
            int tmp1 = start_m * 1000000;
            tmp1 += (start_d * 10000);
            printf("请输入需要查看的结束日期\n");
            inputDate(&end_m, &end_d);
            int tmp2 = end_m * 1000000;
            tmp2 += (end_d * 10000);
            int aa = timeSpan(tmp1,tmp2);
            if(aa > 30)
            {
                printf("最多查看30天的数据,请重新输入!\n");
            }
            else
                break;
        }

        position[5] = start_m / 10 + '0';
        position[6] = start_m % 10 + '0';
        position[7] = start_d / 10 + '0';
        position[8] = start_d % 10 + '0';
        position[9] = '/';
        position[10] = 0;
        endPosition[5] = end_m / 10 + '0';
        endPosition[6] = end_m % 10 + '0';
        endPosition[7] = end_d / 10 + '0';
        endPosition[8] = end_d % 10 + '0';
        endPosition[9] = '/';
        position[10] = 0;
        struct Data* container[300];
        int itr = 0;
        struct Data* dataHeadToDel[100];
        int i_del = 0;
        while(strcmp(position,endPosition) <= 0)
        {
            dataHead = input(position);
            struct Data * p = dataHead->next;
            if(!p)
            {
                free(dataHead);
            }
            else
                dataHeadToDel[itr++] = dataHead;
            while(p)
            {
                printf("%d、",itr+1);
                printSingleData(p);
                container[itr++]= p;
                p = p->next;
            }
            nextDay(position);
        }
        container[itr] = NULL;
    if(!itr)
    {
        printMargin(40);
        printf("未找到该时间段的任何数据!\n");
        printMargin(40);
        printf("按任意键返回上一层\n");
        getchar();
        return 0;
    }
    for(;;)
    {printMargin(40);
    printf("1:按医生筛选数据\n");
     printMargin(40);
    printf("2:按患者ID筛选数据\n");
     printMargin(40);
    printf("3:按科室筛选数据\n");
     printMargin(40);
    printf("0: 退出\n");
    int command;
    for(;;)
    {
        printf("请选择:");
        scanInt(&command,3);
        if((command <0)||(command > 3))
        {
            printf("输入不合法\n");
        }
        else
            break;
    }
    switch(command)
    {
    case 1:
        {
            int id;
            printf("请输入医生ID(8位):");
            for(;;)
            {
                if(scanInt(&id,9) != 8)
                {
                    printf("数据非法!请重新输入\n");
                }
                else
                    break;
            }
            viewByDoctorID(container,id);
            break;
        }
    case 2:
        {
            int id;
            printf("请输入患者ID(8位):");
            for(;;)
            {
                if(scanInt(&id,9) != 8)
                {
                    printf("数据非法!请重新输入\n");
                }
                else
                    break;
            }
            viewByPatientID(container,id);
            break;
        }
    case 3:
        {
            int nn;
            for(int i = 0; i < 5; ++i)
            printf("%d、%s\n",i+1,departments[i]);
            printf("请选择:");
            for(;;)
            {
                scanInt(&nn,3);
                if((nn < 1)||(nn > 5))
                {
                    printf("输入非法\n");
                }
                else
                    break;
            }
            viewByDepart(container,nn-1);
            break;
        }
        case 0: break;
    }
    if(!command)
        break;
    }
    for(int i = 0; i < i_del; ++i)
        clearList(dataHeadToDel[i]);
    return 0;
}

int showPatientsInfo(struct Data *node)
{
    /*日期格式:09020900*/
    int in_mon = node->treatment.hospitalization.ruyuanshijian/1000000;
    int in_day = (node->treatment.hospitalization.ruyuanshijian/10000)%100;
    int in_hou = (node->treatment.hospitalization.ruyuanshijian/100) % 100;
    int out_mon = node->treatment.hospitalization.chuyuanshijian/1000000;
    int out_day = (node->treatment.hospitalization.chuyuanshijian/10000)%100;
    int out_hou = (node->treatment.hospitalization.chuyuanshijian/100) % 100;
    char sexstr[2][4] = {"女","男"};
    int sex = (node->number % 100000) / 10000;
    printf("ID: %d 姓名:%5s 性别:%s 年龄:%2d  ",node->ID,node->name,sexstr[sex],node->age);
    printf("入院时间: %2d月 %2d日 %2d时 预计出院时间: %2d月 %2d日 %2d时  ",in_mon,in_day,in_hou,out_mon,out_day,out_hou);
    time_t now;
    struct tm* tm_now;
    time(&now);
    tm_now = localtime(&now);

    int now_time = (tm_now->tm_mon+1)*1000000 + tm_now->tm_mday * 10000 + tm_now->tm_hour * 100;
    int cost = 200*timeSpan(node->treatment.hospitalization.ruyuanshijian,now_time);
    printf("总缴纳押金:%d",node->treatment.hospitalization.zhuyuanyajin);
    printf("住院押金剩余:%d",node->treatment.hospitalization.zhuyuanyajin - cost);
    if(node->treatment.hospitalization.zhuyuanyajin - cost < 1000)
    {
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(handle, 0xFC);
    printMargin(30);
    printf("余额不足!");
    SetConsoleTextAttribute(handle, 0xF0);
    }
    return 0;
}

//文件change.h
#ifndef ZHANGWY_H_INCLUDED
#define ZHANGWY_H_INCLUDED

int changePatientData(struct Data *p);//修改患者基本信息
int changeDoctorData(struct Doctor *p);//修改数据中的医生信息
int changeMedList(struct Medicine * head);//修改数据中的购药信息
int changeExamList(struct ExaminationFee * head);//修改数据中的检查项目信息
int changeHospitalData(struct Hospitalization *base);//修改数据中的住院信息
int changeData();//修改挂号数据的主界面
#endif // ZHANGWY_H_INCLUDED
//文件change.c
#include 
#include 
#include
#include
#include 
#include 
#include 
#include
#include"basic.h"
#include"view.h"
#include"change.h"
int changePatientData(struct Data *p)
{
    int command;
      for(;;)
    {
        printf("请选择需要修改哪一项:\n");
        printf("1、挂号序列 2、 姓名 3、年龄 4、ID \n");
        scanInt(&command, 2);
        if((command < 1)||(command > 4))
        {
            printf("输入不合法,请检查 \n");
        }
        else
            break;
    }
    switch(command)
    {
    case 1:
        {
            printf("请重新输入挂号序列(9位正整数):");
            for(;;)
            {
                if(scanInt(&(p->number),9)==9)
                    break;
                else
                {
                    printf("请正确输入!\n");
                }
            }
            break;
        }
    case 2:
        {
            printf("修改姓名:");
            scanName(p->name,20);
            break;
        }
    case 3:
        {
            printf("修改年龄:");
            for(;;)
            {
                scanInt(&(p->age), 4);
                if((p->age <0) || (p->age > 140))
                {
                    printf("输入不合法,请检查!\n");
                }
                else
                    break;

            }
            break;

        }
    case 4:
        {
            printf("修改ID(8位正整数):");
            for(;;)
            {
                if(scanInt(&(p->ID),8) == 8)
                    break;
                else
                {
                    printf("请正确输入!\n");

                }
            }
            break;
        }
    }
        printf("修改成功!修改后的患者信息为:");
        printf("挂号序列:%d 患者姓名:%s ID:%d 患者年龄: %d  ", p->number, p->name,p->ID, p->age);

    return 0;
}

int changeData()
{
    system("cls");
    extern struct Data *dataHead;
    struct Data* p = dataHead->next;
    int command;
    struct Data* line[300];
    if(dataHead->next == NULL)
        return -1;
    int i = 0;
    while(p)
    {
        line[i] = p;
        printf("---------------------\n");
        printf("%d、  ",++i);
        printSingleData(p);
        p = p->next;
    }
    line[i] = NULL;
    for(;;)
    {
        printMargin(40);
        printf("1:删除数据\n\n");
        printMargin(40);
        printf("2:修改数据\n\n");
        printMargin(40);
        printf("0:返回上一层\n\n\n\n\n\n\n\n请输入:");
        scanInt(&command,3);
        if((command > 2)||(command <0))
        {
            printf("输入不合法\n");
        }
        else
            break;
    }
    if(!command)
        return 0;
    if(command == 1)
    {
        for(;;)
        {
            printf("您要删除哪条数据?\n");
            int n;
            scanInt(&n,3);
            if((n > i)||(n < 1))
                printf("输入不合法!\n");
            else
            {
                free(line[n-1]);
                if(n == 1)
                    dataHead->next = line[1];
                else
                    line[n-2]->next = line[n];
                break;
            }
        }
        system("cls");
        printf("\n\n\n\n\n\n");
        printMargin(40);
        printf("删除成功!按任意键返回上一层");
        getchar();
        return 0;
    }
    for(;;)
    {
        printf("请输入需要修改的数据序号(输入0返回上一层):");
        scanInt(&command,2);
        if((command > i)||(command < 0))
        {
            printf("请检查输入\n");
        }
        else
            break;
    }
    if(!command)
        return 0;
    p = line[command-1];
    printf("\n\n\n\n");
     printMargin(10);
    printSingleData(p);

    printf("\n\n请选择修改哪项数据?\n\n\n\n\n");
    printMargin(10);
    printf("1:患者基本信息\n\n");
        printMargin(10);
    printf("2:医生信息\n\n");
        printMargin(10);
    printf("3:购药信息\n\n");
        printMargin(10);
    printf("4:检查项目信息\n\n");
        printMargin(10);
    printf("5:住院信息\n\n");
        printMargin(10);
    printf("0:退出页面\n\n");
        printMargin(10);
    for(;;)
    {
        scanInt(&command,3);
        if((command < 0)||(command > 5))
        {
            printf("输入不合法,请检查!\n");
        }
        else
            break;
    }
    switch(command)
    {
        case 1: changePatientData(p);break;
        case 2: changeDoctorData(&(p->doctor));break;
        case 3: changeMedList(&(p->treatment.medicine)); break;
        case 4: changeExamList(&(p->treatment.exminationFee)); break;
        case 5: changeHospitalData(&(p->treatment.hospitalization));break;
        case 0: break;
    }

    system("cls");
    printf("\n\n\n");
    printf("修改后的完整数据:\n");
    printSingleData(p);
    printf("\n\n\n");
    printf("按任意键返回主菜单!");
    getchar();
    return 0;
}



int changeHospitalData(struct Hospitalization *base)
{
    int months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    printf("请输入入院时间,格式:月 日 时如: \"9 10 10\",数字间以空格间隔 \n");
    int m,d,h,s;
    base->zhuyuanyajin = 0;
    for(;;)
    {
        scanInt(&m, 2);
        scanInt(&d, 2);
        scanInt(&h, 2);
        s = 0;
        if((m > 0)&&(m < 13)&&(d > 0)&& (d <= months[m])&&(h >= 0)&&(h < 24)&&(s >= 0)&&(s < 60))
        {
            break;
        }
        printf("请检查输入格式重新输入:");
    }
    int time1 = m * 1000000;
    time1 += (d * 10000);
    time1 += (h * 100);
    base->ruyuanshijian = time1;
    int m1,d1,h1,s1;
    printf("请输入出院时间,格式:月 日 时如: \"9 10 10\",数字间以空格间隔 \n");
    for(;;)
    {
        scanInt(&m1, 2);
        scanInt(&d1, 2);
        scanInt(&h1, 2);
        s1 = 0;
        if((m1 > 0)&&(m1 < 13)&&(d1 > 0)&& (d1 <= months[m])&&(h1 >= 0)&&(h1 < 24))
        {
            int n1 = m;
            n1 = n1 * 40 + d;
            n1 = n1 * 30 + h;
            n1 = n1 * 60 + s;
            int n2 = m1;
            n2 = n2 * 40 + d1;
            n2 = n2 * 30 + h1;
            n2 = n2 * 60 + s1;
            if(n1 < n2)
                break;
            else
            {
                printf("请保证出院时间晚于入院时间\n");
            }
        }
        printf("请重新输入出院时间:");
    }
    time1 = m1 * 1000000;
    time1 += (d1 * 10000);
    time1 += (h1 * 100);
    time1 += (s1);
    base->chuyuanshijian = time1;
    printf("入院时间:%d月 %d日 %d时 ",(base->ruyuanshijian)/1000000,((base->ruyuanshijian)%1000000)/10000,((base->ruyuanshijian)%10000)/100);
    printf("出院时间:%d月 %d日 %d时 \n",(base->chuyuanshijian)/1000000,((base->chuyuanshijian)%1000000)/10000,((base->chuyuanshijian)%10000)/100);
    return 0;

}


int changeMedList(struct Medicine * head)
{




    struct Medicine *p = head->next;
    struct Medicine * line[200];
    int i = 0;
    while(p)
    {
        line[i] = p;
        printf("%d)、  药品名:%s 数量:%d, 单价:%d \n",++i,p->name,p->number,p->price);
        p = p->next;
    }
    line[i] = NULL;
        int command;
        for(;;)
        {
            printf("请选择需要执行的操作:1、增加一条数据 2、删除一条数据 3、修改数据\n");
            scanInt(&command,3);
            if((command >3) || (command < 1))
            {
                printf("输入不合法\n");
            }
            else
                break;
        }
        switch (command)
        {
        case 1://插入一条数据
            {
                struct Medicine * pnew = (struct Medicine *) malloc (sizeof(struct Medicine));
                pnew->next = NULL;
                printf("请输入药品名称:");
                scanStr(pnew->name,14);
                printf("请输入药品单价,\(格式 \" 元 角 \" ,不得超过999元):");
                int m,n;
                for(;;)
                {
                    scanInt(&n,6);
                    scanInt(&m,5);
                    if((n < 0)||(n > 999)||(m > 9)||(m < 0))
                    {
                        printf("请检查输入格式\n");
                    }
                    else
                    {
                        pnew->price = n*10 + m;
                        break;
                    }

                }
                printf("请输入药品数量,不得超过999");
                for(;;)
                {
                    scanInt(&m,4);
                    if((m < 0)||(m > 999))
                    {
                        printf("数据不合法\n");
                    }
                    else
                    {
                        pnew->number = m;
                        break;
                    }
                }
                    head->next = pnew;
                    pnew->next = line[0];
                break;
            }
        case 2://删除一条数据
            {
                if(!i)//链表为空
                {
                    printf("没有可删除的数据\n");
                    break;
                }
                printf("请输入欲删除的数据序号\n");
                for(;;)
                {
                    int command;
                    scanInt(&command,3);
                    if((command < 0)||(command > i))
                    {
                        printf("请检查输入格式!\n");
                    }
                    else
                    {
                        if(command == 1)
                        {
                            free(line[0]);
                            head->next = NULL;
                        }
                        else
                        {
                            free(line[command - 1]);
                            line[command - 2]->next = line[command];
                        }
                        printf("已删除");
                        break;
                    }
                }

                break;
            }

        case 3://修改一条数据
            {
                int command;
                struct Medicine *pp;
                for(;;)
                {
                    printf("请输入欲修改的数据序号:");
                    scanInt( &command, 3);
                    if((command > i)||(command < 0))
                    {
                      printf("输入不合法!\n");
                    }
                    else
                    {
                        pp = line[command - 1];
                        break;
                    }
                }

                printf("请输入药品名称:");
                scanStr(pp->name,14);
                printf("请输入药品单价,(格式 “元 角” ,不得超过999元):");
                int m,n;
                for(;;)
                {
                    scanInt(&n,6);
                    scanInt(&m,5);
                    if((n < 0)||(n > 999)||(m > 9)||(m < 0))
                    {
                        printf("请检查输入格式\n");
                    }
                    else
                    {
                        pp->price = n*10 + m;
                        break;
                    }

                }
                printf("请输入药品数量,不得超过999");
                for(;;)
                {
                    scanInt(&m,4);
                    if((m < 0)||(m > 99))
                    {
                        printf("数据不合法\n");
                    }
                    else
                    {
                        pp->number = m;
                        break;
                    }
                }
                break;

            }
        }
    p = head->next;
    printf("修改后数据:\n");
    while(p)
    {
        line[i] = p;
        printf("%d)、  药品名:%s 数量:%d, 单价:%d \n",++i,p->name,p->number,p->price);
        p = p->next;
    }
        return 0;
}

附件:

工程源文件.zip

注:工程使用codeblocks:: 17.12 with gcc编译

你可能感兴趣的:(C,c语言)