C語言小項目-火車票訂票系統


 

 

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;
}

 

 顯示火車票信息_示意圖:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM