list.h
#ifndef __LIST_H__ #define __LIST_H__ #include "stdafx.h" #include <stdio.h> #include <stdlib.h> //定義單向鏈表節點 typedef struct _node { void *dat; //一般為結構體指針 int size; //dat指向區域的大小,一般為結構體的大小 struct _node *next; //后繼節點 }node; //創建鏈表 extern node *createList(int size); //插入數據到鏈表尾節點后 extern int insertData_toListTail(node *head,void *dat); #endif
list.cpp
#include "stdafx.h" #include "list.h" /*************************************鏈表模塊***************************************************/ //創建鏈表 node *createList(int size) { node *head = (node *)malloc(sizeof(node)); //給鏈表頭結點分配內存空間 if(!head) { printf("listHead malloc error!\n"); return NULL; } head->dat = NULL; //鏈表頭結點不存儲數據,故指向NULL head->size = size; //鏈表的size一般為結構體的大小[size == sizeof(ticket)] head->next = NULL; return head; } //插入數據到鏈表尾節點后 int insertData_toListTail(node *head,void *dat) { node *tmpNode = (node *)malloc(sizeof(node)); //定義一個存儲插入數據的臨時節點,插入該節點就相當於插入數據了 if(!tmpNode) { printf("tmpNode malloc error!\n"); return NULL; } //給臨時節點的數據指針dat分配內存空間 tmpNode->dat = malloc(sizeof(head->size)); //dat的類型一般為struct *,所以不再進行(void *)的強制類型轉換 if (!tmpNode->dat) { printf("tmpNode->dat malloc error!\n"); return NULL; } tmpNode->dat = dat; //將要插入的數據保存在臨時節點內 tmpNode->size = head->size; node *cur = head; //定義當前節點 while(cur->next) //找到尾節點 [若鏈表只有一個頭節點,則頭節點就是尾節點] { cur = cur->next; } //將保存要插入數據的臨時節點,插入到尾節點后 cur->next = tmpNode; tmpNode->next = NULL; //此時,tmpNode變為尾節點 return 0; }
ticket.h
#ifndef __TICKET_H__ #define __TICKET_H__ //定義火車票信息結構體 typedef struct _ticket { char number[10]; //火車票的車次 char startCity[10]; //火車票的出發城市 char reachCity[10]; //火車票的到達城市 char takeoffTime[10]; //火車票的出發時間 char reachTime[10]; //火車票的到達時間 float price; //火車票的票價 int ticketNum; //火車票的剩余票數 }ticket; /*************************************預編譯模塊***************************************************/ #define HEADER1 "|------------------------------book ticket sys--------------------------------|\n" #define HEADER2 "| number |start city|reach city|takeoffTime|reach time| price |ticketNum |\n" #define HEADER3 "|-----------------------------------------------------------------------------|\n" #define FORMAT "|%-10s|%-10s|%-10s|%-11s|%-10s|%-10.2f|%-10d|\n" //除了takeoffTime這一項,為保持上下對齊的美觀,其它項數據都固定只占10位的長度 extern node *g_ticketList; //分配內存空間函數 extern void *mallocMemory(int size); //保存鏈表中的數據到文件中 extern int saveData(node *head,int size); //讀取文本中的數據到鏈表中 extern int readData(node *head,int size); //添加火車票,並保存在火車票信息鏈表中 extern int addTicket_toList(node *head); //根據車次,修改火車票,並馬上保存在火車票信息鏈表中 extern int modifyTicket_byNumber(node *head); //根據車次,刪除火車票,並實時更新 extern int deleteTicket_byNumber(node *head); //顯示火車票信息鏈表中的所有節點數據 extern int showTicketList_allData(node *head); #endif
ticket.cpp
#include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "list.h" #include "man.h" #include "ticket.h" node *g_ticketList = NULL; //分配內存空間函數 void *mallocMemory(int size) { if (size == sizeof(ticket)) { ticket *tmpTicket = (ticket *)malloc(size); return tmpTicket; } else if (size == sizeof(man)) { man *tmpMan = (man *)malloc(size); return tmpMan; } else { printf("error!\n"); return NULL; } } //保存鏈表中的數據到文件中 int saveData(node *head,int size) { FILE *fp; int ret = 0; if( size == sizeof(ticket) ) fp = fopen("ticket.txt","wb"); //打開一個只寫的二進制文本 else if( size == sizeof(man) ) fp = fopen("man.txt","wb"); //打開一個只寫的二進制文本 if(!fp) { printf("fopen error!\n"); return -1; } void *temp = NULL; for(node *cur=head->next;cur!=NULL;cur=cur->next) { if( size == sizeof(ticket) ) temp = (ticket *)cur->dat; //獲取鏈表節點保存的數據 else if( size == sizeof(man) ) temp = (man *)cur->dat; //獲取鏈表節點保存的數據 ret = fwrite(temp,size,1,fp); //將結構體數據寫入二進制文本 if(ret != 1) { printf("fwrite error!\n"); return -1; } } fclose(fp); printf("fwrite success!\n"); return 0; } //讀取文本中的數據到鏈表中 int readData(node *head,int size) { FILE *fp; if( size == sizeof(ticket) ) fp = fopen("ticket.txt","rb"); //打開一個只讀的二進制文本 else if( size == sizeof(man) ) fp = fopen("man.txt","rb"); //打開一個只讀的二進制文本 if(!fp) { printf("fopen error!\n"); return -1; } void *temp = NULL; while(!feof(fp)) { if( size == sizeof(ticket) ) temp = (ticket *)mallocMemory(sizeof(ticket)); //定義一個臨時火車票結構體指針(必須定義在while內,每次讀文件,都必須重新分配內存空間) else if( size == sizeof(man) ) temp = (man *)mallocMemory(sizeof(man)); //定義一個臨時訂票人結構體指針(必須定義在while內,每次讀文件,都必須重新分配內存空間) if( fread(temp,size,1,fp) == 1 ) //讀取二進制文本的結構體數據 { insertData_toListTail(head,temp); //插入數據到鏈表尾節點后 } } fclose(fp); printf("fread success!\n"); return 0; } /*************************************火車票模塊***************************************************/ //添加火車票,並保存在火車票信息鏈表中 int addTicket_toList(node *head) { ticket *tmpTicket = (ticket *)mallocMemory(sizeof(ticket)); //定義火車票信息的臨時結構體指針,並分配內存空間 printf("請輸入火車票的車次:"); scanf("%s",tmpTicket->number); printf("請輸入火車票的出發城市:"); scanf("%s",tmpTicket->startCity); printf("請輸入火車票的到達城市:"); scanf("%s",tmpTicket->reachCity); printf("請輸入火車票的出發時間:"); scanf("%s",tmpTicket->takeoffTime); printf("請輸入火車票的到達時間:"); scanf("%s",tmpTicket->reachTime); printf("請輸入火車票的票價:"); scanf("%f",&tmpTicket->price); printf("請輸入火車票的剩余票數:"); scanf("%d",&tmpTicket->ticketNum); printf("add ticket success!\n"); insertData_toListTail(head,tmpTicket); //插入火車票信息數據,到火車票信息鏈表尾節點后 saveData(g_ticketList,sizeof(ticket)); //保存火車票鏈表中的信息到文件中 return 0; } //根據車次,修改火車票,並馬上保存在火車票信息鏈表中 int modifyTicket_byNumber(node *head) { bool findTicket_flag = false; //找到車次對應火車票的標志位 if(!head->next) //檢測鏈表是否只有一個節點 { printf("list only have one node,error!\n"); //鏈表只有一個節點,則打印錯誤信息,並返回 return -1; } char t_number[10]; printf("請輸入要修改的火車票車次:"); scanf("%s",t_number); ticket *tmpTicket = NULL; for (node *cur=head->next;cur!=NULL;cur=cur->next) { tmpTicket = (ticket *)cur->dat; //獲取火車票信息鏈表節點保存的數據 if ( strcmp(t_number,tmpTicket->number) == 0 ) //檢查輸入車次對應的火車票是否存在 { findTicket_flag = true; printf("請重新輸入火車票的車次:"); scanf("%s",tmpTicket->number); printf("請重新輸入火車票的出發城市:"); scanf("%s",tmpTicket->startCity); printf("請重新輸入火車票的到達城市:"); scanf("%s",tmpTicket->reachCity); printf("請重新輸入火車票的出發時間:"); scanf("%s",tmpTicket->takeoffTime); printf("請重新輸入火車票的到達時間:"); scanf("%s",tmpTicket->reachTime); printf("請重新輸入火車票的票價:"); scanf("%f",&tmpTicket->price); printf("請重新輸入火車票的剩余票數:"); scanf("%d",&tmpTicket->ticketNum); cur->dat = tmpTicket; //將修改后的火車票數據保存在原節點內 printf("modify ticket success!\n"); saveData(g_ticketList,sizeof(ticket)); //保存火車票鏈表中的信息到文件中 break; } } if(!findTicket_flag) { printf("the number isn't exist!\n"); return -1; } return 0; } //根據車次,刪除火車票,並實時更新 int deleteTicket_byNumber(node *head) { bool findTicket_flag = false; //找到車次對應火車票的標志位 if(!head->next) //檢測鏈表是否只有一個節點 { printf("list only have one node,error!\n"); //鏈表只有一個節點,則打印錯誤信息,並返回 return -1; } char t_number[10]; printf("請輸入要刪除的火車票車次:"); scanf("%s",t_number); ticket *tmpTicket = NULL; for (node *lastNode=head;lastNode->next!=NULL;lastNode=lastNode->next) { tmpTicket = (ticket *)lastNode->next->dat; //獲取火車票信息鏈表節點保存的數據 if ( strcmp(t_number,tmpTicket->number) == 0 ) //檢查輸入車次對應的火車票是否存在 { findTicket_flag = true; node *deleteNode = lastNode->next; //“要刪除節點”deleteNode,為“上個節點”lastNode的next節點 lastNode->next = deleteNode->next; //“上個節點”的next指向“要刪除節點”的next,則相當於刪除了“要刪除節點” free(deleteNode->dat); free(deleteNode); //后面要用到deleteNode,所以不能釋放,否則會崩潰 printf("delete ticket success!\n"); saveData(g_ticketList,sizeof(ticket)); //保存火車票鏈表中的信息到文件中 break; } } if(!findTicket_flag) { printf("the number isn't exist!\n"); return -1; } return 0; } //顯示火車票信息鏈表中的所有節點數據 int showTicketList_allData(node *head) { if(!head->next) //檢測鏈表是否只有一個節點 { printf("list only have one node,error!\n"); //鏈表只有一個節點,則打印錯誤信息,並返回 return -1; } ticket *tmpTicket = NULL; //定義火車票信息的臨時結構體指針 printf(HEADER1); //打印輸出頭信息 printf(HEADER2); printf(HEADER3); for(node *cur=head->next;cur!=NULL;cur=cur->next) //由於頭節點不保存數據,所以從第二個節點開始顯示數據 { tmpTicket = (ticket *)cur->dat; //將節點數據取出來,賦給臨時結構體指針 printf(FORMAT,tmpTicket->number,tmpTicket->startCity,tmpTicket->reachCity,tmpTicket->takeoffTime,tmpTicket->reachTime,tmpTicket->price,tmpTicket->ticketNum); } return 0; }
man.h
#ifndef __MAN_H__ #define __MAN_H__ //定義訂票人結構體 typedef struct _man { int ID; //ID身份證號碼 char name[10]; //名字 int bookNum; //訂票數目 }man; extern node *g_manList; //外部聲明一個全局訂票人信息鏈表 //顯示訂票人信息鏈表中的所有節點數據 extern int showManList_allData(node *head); //訂票函數 extern int bookTicket(node *head); #endif
man.cpp
#include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "list.h" #include "ticket.h" #include "man.h" node *g_manList = NULL; //定義一個全局訂票人信息鏈表 //顯示訂票人信息鏈表中的所有節點數據 int showManList_allData(node *head) { if(!head->next) //檢測鏈表是否只有一個節點 { printf("list only have one node,error!\n"); //鏈表只有一個節點,則打印錯誤信息,並返回 return -1; } man *tmpMan = NULL; //定義訂票人信息的臨時結構體指針 for(node *cur=head->next;cur!=NULL;cur=cur->next) //由於頭節點不保存數據,所以從第二個節點開始顯示數據 { tmpMan = (man *)cur->dat; //將節點數據取出來,賦給臨時結構體指針 printf("%d %s %d\n",tmpMan->ID,tmpMan->name,tmpMan->bookNum); } return 0; } //訂票函數 int bookTicket(node *head) { bool findTicket_flag = false; //找到車次對應火車票的標志位 if(!g_ticketList->next) //檢測火車票信息鏈表是否只有一個節點 { printf("g_ticketList only have one node,error!\n"); //鏈表只有一個節點,則打印錯誤信息,並返回 return -1; } char t_reachCity[10]; printf("請輸入你要去的城市:"); scanf("%s",t_reachCity); ticket *tmpTicket = NULL; node *cur; for (cur=head->next;cur!=NULL;cur=cur->next) { tmpTicket = (ticket *)cur->dat; //獲取火車票信息鏈表節點保存的數據 if ( strcmp(t_reachCity,tmpTicket->reachCity) == 0 ) //檢查輸入城市對應的火車票是否存在 { findTicket_flag = true; printf(FORMAT,tmpTicket->number,tmpTicket->startCity,tmpTicket->reachCity,tmpTicket->takeoffTime,tmpTicket->reachTime,tmpTicket->price,tmpTicket->ticketNum); break; } } if(!findTicket_flag) { printf("the number isn't exist!\n"); return -1; } char cmd; printf("Do you want book ticket?(y/n): "); getchar(); //吸收上次輸入的"ENTER" scanf("%c",&cmd); if (cmd == 'y') { ; } else if (cmd == 'n') { return -1; } else { printf("cmd error!\n"); return -1; } man *tmpMan = (man *)mallocMemory(sizeof(man)); //定義一個臨時訂票人結構體指針,並分配內存空間 printf("請輸入你的ID:"); scanf("%d",&tmpMan->ID); printf("請輸入你的姓名:"); scanf("%s",tmpMan->name); printf("請輸入你的訂票數目:"); scanf("%d",&tmpMan->bookNum); //更新該車次火車票的剩余票數 tmpTicket->ticketNum -= tmpMan->bookNum; cur->dat = tmpTicket; insertData_toListTail(g_manList,tmpMan); //插入訂票人數據到鏈表尾節點后 printf("book ticket success!\n"); saveData(g_manList,sizeof(man)); return -1; }
bookTicketSys.cpp (包含主函數)
#include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "list.h" #include "man.h" #include "ticket.h" void menu() { printf("1. add ticket \n"); printf("2. modify ticket \n"); printf("3. delete ticket \n"); printf("4. book ticket \n"); printf("5. show ticket \n"); printf("6. show man \n"); printf("7. save \n"); } int _tmain(int argc, _TCHAR* argv[]) { int sel = 0; g_ticketList = createList(sizeof(ticket)); //創建火車票信息鏈表 g_manList = createList(sizeof(man)); //創建火車票信息鏈表 readData(g_ticketList,sizeof(ticket)); //讀取火車票文件 readData(g_manList,sizeof(man)); //讀取訂票人文件 do { menu(); //顯示菜單選項 printf("請輸入你的選項:"); scanf("%d",&sel); switch(sel) { case 1: { addTicket_toList(g_ticketList); //添加火車票信息,到火車票鏈表中 } break; case 2: { modifyTicket_byNumber(g_ticketList); //根據車次,修改火車票,並馬上保存在火車票信息鏈表中 } break; case 3: { deleteTicket_byNumber(g_ticketList); //根據車次,刪除火車票,並實時更新 } break; case 4: { bookTicket(g_ticketList); //訂票 } break; case 5: { showTicketList_allData(g_ticketList); //顯示火車票信息鏈表中的所有節點數據 } break; case 6: { showManList_allData(g_manList); //顯示訂票人信息鏈表中的所有節點數據 } break; case 7: { saveData(g_ticketList,sizeof(ticket)); //保存火車票鏈表中的信息到文件中 } break; } system("PAUSE"); //暫停 system("CLS"); //清屏 } while (sel!=7); return 0; }
顯示火車票信息_示意圖: