大一C语言编程题?

完成下面的售票系统项目系统中有5个车站,车站包括站名和独有id编号,程序自动生成车站名和独有的id编号。系统将根据车站随机生成车票,车票信息包括:始发站名、终点站名、票价... 完成下面的售票系统项目

系统中有5个车站,车站包括站名和独有id编号,程序自动生成车站名和独有的id编号。

系统将根据车站随机生成车票,车票信息包括:始发站名、终点站名、票价等信息。

车票信息自动生成,车票总数量不少于20张。

进入系统后菜单如下:

*************************

(1) Buy ticket

(2) Refund ticket

(3) Remove ticket

(4) Display all tickets

(0) Exit

*************************

Please select:

1)进入购买车票菜单后,提示用户输入始发站站名和终点站站名,然后显示当前是否有用户选择的始发站和终点站的车票。

如果有,则显示始发站名、终点站名和剩余票数。并提示用户是否订票,并根据用户输入完成订票。

如果无,则回到主菜单。

2)进入退票菜单后,显示所有已经被预定的车票,提示用户是否进行退票,并根据用户输入完成退票或回到主菜单。

3)进入删除车票菜单后,显示所有车票信息,并提示用户是否进行删除车票,并根据用户输入完成删除车票或者回到主菜单。

4)直接显示所有车票信息。

0)退出程序

求完整代码,十分感谢!
展开
 我来答
自我编程
2020-04-28 · 科技优质答主
自我编程
采纳数:1481 获赞数:4279

向TA提问 私信TA
展开全部

车票根据题意两两站点连线生成,金额和数量分别用随机数。

数据存储:站点,车票,用户分别为3个结构体,用于对应数据库。

购买流程:检查输入数值有效性->检查车票库存->购买成功同步修改用户购买流水及车票库存。(这里题目需求不明确,没有指明用户购买方式),我的代码允许一个用户同时购买多种票,每种票可分批购买多张。购买流水记录自动增加和更新。

退票流程:检查输入和用户购买记录,同步更新用户及车票信息。

删除流程:选择删除没有被用户购买的票(函数检查所有用户,虽然本题只要一个用户,实际传参用户数组首地址)。

PS: 这个题目涉及到增删改,用链表来写更好,但考虑你学习范围,没有使用链表而是动态数组,动态数组删除,考虑内存占用,不仅要需循环移位还要释放多余地址。

另外整体程序,异常的处理我只是单纯返回0或者1或者-1区分基本的成功与失败。你如想对个别异常进行特殊处理,自行修改返回值,接收判断。

下面是代码:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

#include <windows.h>

#include <conio.h>

#define MS 5//最大站点数

typedef struct station

{

    char sid[10];

    char sName[20];

}STN;

typedef struct ticket

{

    int tid;//票编号

    STN *ssP;//起始站

    STN *tsP;//终点站

    int value;//票价

    int number;//数量

}TKT;

typedef struct userInfo//用户

{

    char uid[20];//身份证号

    int cnt;//购买的票种类数量

    int *btids;//购买的所有票id数组

    int *btNum;//购买的所有票数量数组

}UIFO;

int init(STN stns[MS],TKT **tkts);//初始化车站、票数据

int disAllTickets(TKT *tkts);

int buyTicket(UIFO *uifo,TKT *tkts);//异常返回0

int reTicket(UIFO *uifo,TKT *tkts);//异常返回0

int showMenu(UIFO *uifo,TKT *tkts);

int delIntByIndex(int *nums,int len,int index);//通过下标index删除动态整型数组nums对应元素,并释放多余地址,返回删除后的数组长度,异常返回-1

int delTkts(UIFO *uifos,int len,TKT *tkts);//删除指定票(检查用户组,只要有一个用户购买,无法删除)

int cnt;//票种类数量

int main()

{


    STN stns[MS];

    TKT *tkts=NULL;

    UIFO uifo={"321002199902050614",0,NULL,NULL};

    srand(time(NULL));

    cnt=init(stns,&tkts);

    printf("共生成%d组票(每组往返两种票,共%d种票)\n\n",cnt/2,cnt);

    printf("按任意键继续。。。。\n"),getch();

    system("cls");

    showMenu(&uifo,tkts);

    return 0;

}

int showMenu(UIFO *uifo,TKT *tkts)

{

    int n=5;

    printf("(1) Buy ticket\n");

    printf("(2) Refund ticket\n");

    printf("(3) Remove ticket\n");

    printf("(4) Display all tickets\n");

    printf("(0) Exit\n");

    while(n<0 || n>4)

        scanf("%d",&n);

    switch(n)

    {

        case 0: return 0;

        case 1: if(!buyTicket(uifo,tkts)) return 0;break;

        case 2: if(!reTicket(uifo,tkts)) return 0;break;

        case 3: if(!delTkts(uifo,1,tkts)) return 0;break;

        //这里删除功能,用户多名,要传数组首地址,由于演示只有一个用户(len=对应用户数),所以只传该用户地址(len=1)

        case 4: disAllTickets(tkts);break;

    }

    showMenu(uifo,tkts);

    return 1;

}

int disAllTickets(TKT *tkts)

{

    int i;

    for(i=0;i<cnt;i++)

        printf("编号:%2d 路程:%s-%s 票价:%3d 剩余票数:%d\n",tkts[i].tid,tkts[i].ssP->sName,tkts[i].tsP->sName,tkts[i].value,tkts[i].number);

    printf("按任意键继续。。。。\n"),getch();

    system("cls");

    return 1;

}

int delIntByIndex(int *nums,int len,int index)

{

    int i,*temp=NULL;

    if(index>len-1) return -1;

    for(i=index;i<len-1;i++)

        nums[i]=nums[i+1];

    len--;

    if(len)

    {

        temp=(int *)realloc(nums,sizeof(int)*len);

        if(!temp) return -1;

        nums=temp;

    }

    else

        free(nums);

    return len;

}

int reTicket(UIFO *uifo,TKT *tkts)

{

    int i,j,tid,n,index,len,flag=0;

    printf("当前用户购买记录:\n");

    for(i=0;i<uifo->cnt;i++)

    {

        for(j=0;j<cnt;j++)

            if(tkts[j].tid==uifo->btids[i]) index=j;

        printf("--车票编号:%d,起末站:%s-%s,购买票数:%d\n",uifo->btids[i],tkts[index].ssP->sName,tkts[index].tsP->sName,uifo->btNum[i]);

    }

    printf("请输入要退票的车票id及票数:"),scanf("%d%d",&tid,&n);

    for(i=0;i<uifo->cnt;i++)

        if(uifo->btids[i]==tid && uifo->btNum[i]>=n)

        {

            for(j=0;j<cnt;j++)

                if(tkts[j].tid==uifo->btids[i]) tkts[j].number+=n;//同步修改对应车票剩余票数

            uifo->btNum[i]-=n;//用户购买记录修改

            if(uifo->btNum[i]==0)//某种车票全部退完,删除该条记录

            {

                len=delIntByIndex(uifo->btNum,uifo->cnt,i);

                if(len==-1) return 0;

                len=delIntByIndex(uifo->btids,uifo->cnt,i);

                if(len==-1) return 0;

                uifo->cnt=len;

            }

            flag=1;

            break;

        }

    if(flag)

        printf("退票成功!\n");

    else

        printf("无此购买记录或输入数量不符合\n");

    printf("按任意键继续。。。。\n"),getch();

    system("cls");

    return 1;

}

int buyTicket(UIFO *uifo,TKT *tkts)

{

    char spn[20],tpn[20];

    int i,n=-1,index=-1,*temp=NULL;

    for(i=0;i<cnt;i++)

        printf("编号:%2d 路程:%s-%s 票价:%3d 剩余票数:%d\n",tkts[i].tid,tkts[i].ssP->sName,tkts[i].tsP->sName,tkts[i].value,tkts[i].number);

    printf("请输入始发站站名和终点站站名:"),scanf("%s%s",spn,tpn);

    for(i=0;i<cnt;i++)

        if(strcmp(tkts[i].ssP->sName,spn)==0 && strcmp(tkts[i].tsP->sName,tpn)==0)

        {

            printf("车票%s-%s 票价:%3d 剩余票数:%d\n",tkts[i].ssP->sName,tkts[i].tsP->sName,tkts[i].value,tkts[i].number);

            index=i;

            break;

        }

    if(index==-1)

        printf("购买失败!无此路程的车票\n");

    else

    {

        while(n<=0)

        {

            printf("请输入要购买的数量(大于0):"),scanf("%d",&n);

            if(tkts[index].number<n)

                printf("错误:车票数量不足或者输入数值超出范围!请重新输入!\n"),n=-1;

        }

        for(i=0;i<uifo->cnt;i++)//检查用户购买记录,重复票累加购买数量,不同票新增记录

        {

            if(uifo->btids[i]==tkts[index].tid)

            {

                printf("该票已购买了%d张,现再次购买%d张,累计购买了%d张\n",uifo->btNum[i],n,uifo->btNum[i]+n);

                uifo->btNum[i]+=n;

                tkts[index].number-=n;

                break;

            }

        }

        if(i==uifo->cnt)//未检查到重复记录,新增

        {

            if(!uifo->btids)

            {

                uifo->btids=(int *)malloc(sizeof(int));

                if(!uifo->btids) return 0;

                uifo->btNum=(int *)malloc(sizeof(int));

                if(!uifo->btNum) return 0;

            }

            else

            {

                temp=(int *)realloc(uifo->btids,sizeof(int)*(uifo->cnt+1));

                if(!temp) return 0;

                uifo->btids=temp;

                temp=(int *)realloc(uifo->btNum,sizeof(int)*(uifo->cnt+1));

                if(!temp) return 0;

                uifo->btNum=temp;

            }

            uifo->btids[uifo->cnt]=tkts[index].tid;

            printf("该票购买了%d张\n",(uifo->btNum[uifo->cnt]=n));

            tkts[index].number-=n;

            uifo->cnt++;

            printf("用户购买记录:\n");

            for(i=0;i<uifo->cnt;i++)

                printf("--车票编号:%d,购买票数:%d\n",uifo->btids[i],uifo->btNum[i]);

        }

        printf("本次成功购买了%s-%s的票%d张!\n",tkts[index].ssP->sName,tkts[index].tsP->sName,n);

    }

    printf("按任意键继续。。。。\n"),getch();

    system("cls");

    return 1;

}

int delTkts(UIFO *uifos,int len,TKT *tkts)//len:所有购买的用户数量

{

    int i,j,k,tid,flag=0,index;

    for(i=0;i<cnt;i++)

        printf("编号:%2d 路程:%s-%s 票价:%3d 剩余票数:%d\n",tkts[i].tid,tkts[i].ssP->sName,tkts[i].tsP->sName,tkts[i].value,tkts[i].number);

    printf("请输入要删除的车票编号:"),scanf("%d",&tid);

    for(i=0;i<cnt;i++)

        if(tid==tkts[i].tid)

        {

            index=i;

            flag=1;

            for(j=0;j<len;j++)//检查所有用户购买记录

            {

                for(k=0;k<uifos[j].cnt;k++)

                    if(uifos[j].btids[k]==tid)

                    {

                        flag=0;

                        printf("该票已被用户购买,无法删除,需先完成退票!\n");

                        break;

                    }

                if(!flag)

                    break;

            }

            break;

        }

    if(!flag) printf(" 删除失败,输入数值超出范围或不可删除!\n");

    else

    {

        cnt--;

        if(cnt==0)

        {

            free(tkts[index].ssP);

            free(tkts[index].tsP);

            free(&tkts[index]);

        }

        else

        {

            free(tkts[index].ssP);

            free(tkts[index].tsP);

            for(i=index;i<cnt;i++)

                tkts[i]=tkts[i+1];

            tkts[cnt].ssP=NULL;

            tkts[cnt].tsP=NULL;

            free(&tkts[cnt]);

        }

        printf(" 删除成功!\n");

    }

    printf("按任意键继续。。。。\n"),getch();

    system("cls");

    return 1;

}

int init(STN stns[MS],TKT **tkts)

{

    TKT *tTemp=NULL;

    int i,j,n,v,cnt=2;

    static int id=1;

    printf("生成站点:\n");

    for(i=0;i<MS;i++,id++)

    {

        sprintf(stns[i].sid,"车站%03d",id);

        sprintf(stns[i].sName,"SN%03d",id);

        printf("----站点名:%s。站点ID:%s\n",stns[i].sid,stns[i].sName);

    }

    printf("计算所有站点连线,生成车票(票是往返,所以一次生成往返两组票):\n");

    for(i=0;i<MS;i++)

        for(j=i+1;j<MS;j++)

        {

            if(!(*tkts))

            {

                *tkts=(TKT *)malloc(sizeof(TKT)*2);

                if(!(*tkts)) return -1;

            }

            else

            {

                tTemp=(TKT *)realloc((*tkts),sizeof(TKT)*cnt);

                if(!tTemp) return -1;

                *tkts=tTemp;

            }

            n=rand()%4+2;//每种票随机2~5张(保证总数大于20)

            v=rand()%201+50;//随机生成票价50~250

            (*tkts)[cnt-1].tid=cnt;

            (*tkts)[cnt-1].ssP=&stns[i];

            (*tkts)[cnt-1].tsP=&stns[j];

            (*tkts)[cnt-1].value=v;

            (*tkts)[cnt-1].number=n;

            (*tkts)[cnt-2].tid=cnt-1;

            (*tkts)[cnt-2].ssP=&stns[j];

            (*tkts)[cnt-2].tsP=&stns[i];

            (*tkts)[cnt-2].value=v;

            (*tkts)[cnt-2].number=n;

            printf("----%s和%s的之间往返票各生成%d张,票价为%d(随机)\n",stns[i].sName,stns[j].sName,n,v);

            cnt+=2;

        }

    return cnt-2;

}

//答题不易,如采纳的,请不要无故删除问题。

推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式