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! "); 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! "); return NULL; } //给临时节点的数据指针dat分配内存空间 tmpNode->dat = malloc(sizeof(head->size)); //dat的类型一般为struct *,所以不再进行(void *)的强制类型转换 if (!tmpNode->dat) { printf("tmpNode->dat malloc error! "); 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--------------------------------| " #define HEADER2 "| number |start city|reach city|takeoffTime|reach time| price |ticketNum | " #define HEADER3 "|-----------------------------------------------------------------------------| " #define FORMAT "|%-10s|%-10s|%-10s|%-11s|%-10s|%-10.2f|%-10d| " //除了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! "); 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! "); 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! "); return -1; } } fclose(fp); printf("fwrite success! "); 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! "); 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! "); 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! "); 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! "); //链表只有一个节点,则打印错误信息,并返回 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! "); saveData(g_ticketList,sizeof(ticket)); //保存火车票链表中的信息到文件中 break; } } if(!findTicket_flag) { printf("the number isn't exist! "); return -1; } return 0; } //根据车次,删除火车票,并实时更新 int deleteTicket_byNumber(node *head) { bool findTicket_flag = false; //找到车次对应火车票的标志位 if(!head->next) //检测链表是否只有一个节点 { printf("list only have one node,error! "); //链表只有一个节点,则打印错误信息,并返回 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! "); saveData(g_ticketList,sizeof(ticket)); //保存火车票链表中的信息到文件中 break; } } if(!findTicket_flag) { printf("the number isn't exist! "); return -1; } return 0; } //显示火车票信息链表中的所有节点数据 int showTicketList_allData(node *head) { if(!head->next) //检测链表是否只有一个节点 { printf("list only have one node,error! "); //链表只有一个节点,则打印错误信息,并返回 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! "); //链表只有一个节点,则打印错误信息,并返回 return -1; } man *tmpMan = NULL; //定义订票人信息的临时结构体指针 for(node *cur=head->next;cur!=NULL;cur=cur->next) //由于头节点不保存数据,所以从第二个节点开始显示数据 { tmpMan = (man *)cur->dat; //将节点数据取出来,赋给临时结构体指针 printf("%d %s %d ",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! "); //链表只有一个节点,则打印错误信息,并返回 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! "); 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! "); 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! "); 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 "); printf("2. modify ticket "); printf("3. delete ticket "); printf("4. book ticket "); printf("5. show ticket "); printf("6. show man "); printf("7. save "); } 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; }
显示火车票信息_示意图: