#include <stdio.h> #include <stdlib.h> #include <string.h> #define LEN sizeof(GUEST) #define FILENAME_LEN 10 #define NULL 0 #define FORMAT "\n%20d%20s%20d\n" #define TRUE 1 #define FALSE 0 struct guest { int number; /*客号*/ char name[10]; /*姓名*/ int money; /*金额*/ struct guest *pNext; }; typedef struct guest GUEST; /*函数的初始化*/ GUEST *Creat(void); GUEST *Delect(GUEST *pHeadGet, int numSelect); GUEST *ReadList(void ); char WelcomeAndTip(void); void Insert(GUEST *pHeadGet, int numInsert); void Show(GUEST *pHeadGet); void Max_Print(GUEST *pHeadGet); void ListSave(GUEST *pHeadGet); void FoundAndPrint(GUEST *pHeadGet, int number); void Update(GUEST *pHeadGet, int number, int newMoney); /* =========================== 功能:main,对各个函数进行选择 返回:void =========================== */ void main() { GUEST *pHead = NULL; char select; int client, number; SELECT: select = WelcomeAndTip(); /*欢迎界面*/ switch(select) { case 'I' :case 'i' : if (pHead == NULL) { pHead = Creat(); system("cls"); Show(pHead); } else { system("cls"); printf("\n链表已经从文件读入存在\n"); } break; case 'D' :case 'd' : system("cls"); Show(pHead); printf("\n请输入您要删除的客号:"); scanf("%d", &client); pHead = Delect(pHead, client); system("cls"); Show(pHead); break; case 'S' :case 's' : printf("请输入您要插入记录的id(不要超过当前链表的长度):"); scanf("%d", &client); Insert(pHead, client); system("cls"); Show(pHead); break; case 'Q' :case 'q': system("cls"); Show(pHead); break; case 'M' :case 'm': Max_Print(pHead); break; case 'B' :case 'b': ListSave(pHead); break; case 'R' :case 'r': pHead = ReadList(); system("cls"); Show(pHead); break; case 'F' :case 'f': /*用number作为内部的唯一id,名字会有重名*/ system("cls"); Show(pHead); printf("\n请输入您要查询的客号:"); scanf("%d", &client); system("cls"); FoundAndPrint(pHead, client); break; case 'C':case 'c': system("cls"); Show(pHead); printf("\n请输入要宾客的客号和结算金额(用空格隔开):"); scanf("%d%d", &number, &client); system("cls"); Update(pHead, number, client); break; default : system("pause"); system("cls"); printf("\n请重新选择\n"); break; } goto SELECT; } /* =========================== 功能:打印开始的欢迎消息和操作提示 返回:void 传入:void =========================== */ char WelcomeAndTip(void) /*欢迎和提示界面*/ { int client; char select; printf("\t\t\t 酒店管理(文件操作)\n"); for( client =0; client < 80; client++) { printf("="); } printf("\n"); printf("I:创建\tD:删除\tQ:显示\tS:插入\tM:最大\tB:保存\tR:读入\tF:查找\tC:结算\n"); for( client =0; client < 80; client++) { printf("="); } printf("\n请输入您要进行的操作:"); scanf("%c", &select); return select; } /* =========================== 功能:输出整个节点 返回:void 传入:链表的头指针 =========================== */ void Show(GUEST *pHeadGet) { GUEST *pClient; pClient = pHeadGet; if(pClient == NULL) { printf("\n数据为空没有数据可以打印\n"); } else { printf("\t\t客号\t\t姓名\t\t\t金额"); do { printf(FORMAT, pClient->number, pClient->name, pClient->money); pClient = pClient->pNext; }while(pClient != NULL); } } /* ========================================================= 功能:创造整个节点,不对输入的数据进行控制,和错误判断。 返回:链表头指针 传入:void ========================================================= */ GUEST *Creat(void) { GUEST *pHead = NULL, *pOne = NULL, *pTwo = NULL; int numberTemp = 1; pOne = (GUEST *) malloc(LEN); if(pOne == NULL) { printf("\n开辟不成功请重试\n"); } else { pTwo = pOne; pHead = pOne; pTwo->pNext = NULL; printf("\n请输入第%d个的客号,金额,用空格相隔,以0 0结束输入:", numberTemp); scanf("%d%d", &pOne->number, &pOne->money); _flushall(); printf("\n请输入第%d个宾客的名字: ", numberTemp); gets(pOne->name); } while (pOne->number != 0) { pTwo = pOne;//在开辟之前,前应该给后面的指针赋予前面的指针 pOne = (GUEST *) malloc(LEN); numberTemp++; printf("\n请输入第%d个的客号,金额,用空格相隔:", numberTemp); scanf("%d%d", &pOne->number, &pOne->money); _flushall(); printf("\n请输入第%d个宾客的名字: ", numberTemp); gets(pOne->name); pTwo->pNext = pOne; } pTwo->pNext = NULL; free(pOne); pOne = NULL; // free(pTwo); 空间没有开辟,何来释放 // pTwo = NULL; return(pHead); } /* ====================================== 功能:删除指定客号的节点 返回:void 传入:链表的头指针和要删除的结点次序 ====================================== */ GUEST *Delect(GUEST *pHeadGet, int numSelect) { GUEST *pOne = NULL, *pTwo = NULL; pOne = pHeadGet; if (pHeadGet == NULL) { printf("\n数据为空没有数据可以删除\n"); } else { while( (pOne->number != numSelect) && (pOne->pNext != NULL) ) { pTwo = pOne; pOne = pOne->pNext; } if( numSelect == pOne->number ) { if(pOne == pHeadGet) { pHeadGet = pOne->pNext; free(pOne); } else { pTwo->pNext = pOne->pNext; free(pOne); } } else { printf("\n没有找到要删除的宾客:\n"); } } return pHeadGet; /*若数据位于头节需要返回头一节*/ } /* =========================== 功能: 查找制定客号的数据 返回:void 传入:pHead(头指针), number(客号) =========================== */ void FoundAndPrint(GUEST *pHeadGet, int number) { GUEST *pClient = NULL; int temp = FALSE; pClient = pHeadGet; if(pClient == NULL) { printf("\n数据为空没有数据可以查找\n"); } else { while(pClient != NULL) { if (number == pClient->number) { printf("\t\t客号\t\t姓名\t\t\t金额"); printf(FORMAT, pClient->number, pClient->name, pClient->money); temp = TRUE; break; } pClient = pClient->pNext; } if (!temp) { printf("\n没有找到您要的数据,请核实!\n"); } } } /* =========================== 功能:指定处(数据的那一条的后面)插入节点 返回:void 传入:链表的头指针和插入的位置 =========================== */ void Insert(GUEST *pHeadGet, int numInsert) { GUEST *pOne = NULL, *pTwo = NULL, *pInsert = NULL; int temp; pTwo = pOne = pHeadGet; /*这里的算法很糟糕,怎样快速定位指定的节点?*/ for( temp = 1; temp < numInsert; temp++ ) { pTwo = pTwo->pNext; } pOne = pTwo->pNext; pInsert = (GUEST *) malloc(LEN); printf("\n请输入该客号,金额,用空格相隔:"); scanf("%d%d", &pInsert->number, &pInsert->money); _flushall(); printf("\n请输入插入宾客名字: "); gets(pInsert->name); pTwo->pNext = pInsert; pInsert->pNext = pOne; } /* =========================== 功能:找到最大的消费金额的宾客数据并打印 返回:void 传入:链表的头指针 =========================== */ void Max_Print(GUEST *pHeadGet) { int max; GUEST *pScan = NULL, *pPut = NULL; if (pHeadGet == NULL) { printf("\n数据为空没有数据可以比较\n"); } else { max = pHeadGet->money; pScan = pHeadGet->pNext; pPut = pHeadGet; /*初始化打印节点*/ if(pScan != NULL) /*判断是不是为一个节点的链表*/ { do { if(pScan->money > max) { max = pScan->money; pPut = pScan; } else { pPut = pHeadGet; } pScan = pScan->pNext; } while(pScan != NULL); } system("cls"); printf("金额最好的宾客:\n"); printf("\t\t客号\t\t姓名\t\t\t金额"); printf(FORMAT, pPut->number, pPut->name, pPut->money); } } /* ============================================================ 功能:更新客户当前的消费。 当一个客户消费时,若累积消费总金额大于10000万元, 此次就打6折,大于5000万元,打8折;大于1000 元,打9折, 并更新文件中此客户的消费总金额。 返回:void 传入:pHead(链表的头指针),number(客号),newMoney(最新消费) ============================================================ */ void Update(GUEST *pHeadGet, int number, int newMoney) { GUEST *pClient = NULL; int temp = FALSE; pClient = pHeadGet; if(pClient == NULL) { printf("\n数据为空没有数据可以更新的\n"); } else { while(pClient != NULL) { if (number == pClient->number) { if(pClient->money > 10000) printf("\n这位宾客需要付款:%d\n", (int)(newMoney * 0.6)); else if ((pClient->money < 10000) && (pClient->money > 5000)) printf("\n这位宾客需要付款:%d\n", (int)(newMoney * 0.8)); else printf("\n这位宾客需要付款:%d\n", newMoney); pClient->money += newMoney; temp = TRUE; break; } pClient = pClient->pNext; } if (!temp) { printf("\n没有找到您要更新的数据项,请核实!\n"); } } } /* =========================== 功能:保存当前链表为文件 返回:void 传入:链表的头指针 =========================== */ void ListSave(GUEST *pHeadGet) { FILE *fposition = NULL; char fileName[FILENAME_LEN]; GUEST *pOne = pHeadGet; int listLen = 0; if (pHeadGet == NULL) { printf("\n数据为空没有数据可以保存\n"); } else { while (pOne) { pOne = pOne ->pNext; listLen++; } /*得到链表的长度*/ printf("\n请输入文件名,以txt方式(*.txt):"); _flushall(); gets(fileName); if ((fposition = fopen (fileName, "w")) == NULL) { printf("\n打开文件失败\n"); exit(0); } pOne = pHeadGet; // fprintf(fposition, "\t\t客号\t\t姓名\t\t\t金额"); while (pOne != NULL) { if (! fprintf(fposition, FORMAT, pOne->number,pOne->name, pOne->money)) { printf("\n读入文件出错\n"); } pOne = pOne->pNext; } fclose(fposition); } } /* =========================== 功能:读入文件并创建为当前链表 返回:pHead 传入:void =========================== */ GUEST *ReadList(void) { FILE *fposition = NULL; char fileName[FILENAME_LEN]; GUEST *pOne = NULL, *pTwo = NULL, *pHead = NULL; printf("\n请输入您要打开的文件名,以txt方式(*.txt):"); _flushall(); gets(fileName); if ((fposition = fopen (fileName, "r")) == NULL) { printf("\n打开文件失败\n"); exit(0); } pOne = (GUEST *) malloc(LEN); pTwo = pOne; pHead = pOne; pHead->pNext = NULL; // fseek(fposition, (long)60L, 0); while (!feof(fposition)) { if (!fscanf(fposition, FORMAT, &pOne->number, &pOne->name, &pOne->money)) printf("\n读入文件出错,可能文件为空,或文件不存在!\n"); pTwo = pOne; pOne = (GUEST *) malloc(LEN); pTwo->pNext = pOne; } pTwo->pNext = NULL; free(pOne); /*释放多余的创建*/ pOne = NULL; return pHead; } 
|