list.h
#ifndef __LIST_H__#define __LIST_H__#include "stdafx.h"#include#include //定义单向链表节点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#include #include #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#include #include #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#include #include #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;}
显示火车票信息_示意图: