时间:2021-05-19
程序设计要求用C语言写一个简单的火车售票系统,主要实现的功能为:
录入班次信息
浏览班次信息
按班次号查询
按终点站查询
按余票数量排序保存
售票
退票
更新班次信息
退出系统
所有的班次信息保存在number.dat文件中,排序过后的保存在sort.dat中(.dat是一种二进制文件)。
在编写的过程中我觉得在判断火车的状态比较值得深究。这里假设火车主要有四种状态:
1.未发车
2.已发车
3.停止检票
4.停止退票
在程序中,思路是将代表发车时间的字符串转化为整型,再和系统现在的时间进行大小比较,主要采用if判断各种情况。其中atime代表的是发车时间的整型数,btime代表的是系统时间的整型数,具体实现如下:
if(atime<=btime) //已经发车return 1;if(((atime-btime<=30)&&(atime-btime>5)&&(atime/100==btime/100))||(((atime%100+(60-btime%100))<=30)&&(atime%100+(60-btime%100))>5&&(atime/100-btime/100==1))) //距发车半小时以内,停止退票,%表示取余return 2;if(((atime-btime<=5)&&(atime/100==btime/100))||((atime%100+(60-btime%100)&&(atime/100-btime/100==1))<=5)) //距发车前五分钟内停止检票return 3;return 0; //可以办理购退票在判断退票时如果两个时间的小时数是一样的,则它们的分钟数如果相差在30之内即半小时之内或者发车时间的小时和系统时间的小时相差一个1,并且发车时间的分钟数小于30,系统时间的分钟大于30,则它们之间也就相差在30之内,此时代表停止退票。
判断检票和上面思想大致相同。
为了参考研究,贴上代码:
#include<stdio.h>#include<stdlib.h>#include<conio.h>#include<string.h>#include "time.h"//班次信息表#define SIZELIMIT 10 //每班次的具体信息的字符个数限制在10以内#define MAXNUM 1000 //设定最多只能录入1000个车次信息typedef struct cardbase //定义一个关于班次信息的结构体,取名为CardBase{char C_ID[SIZELIMIT];//班次char C_TIME[SIZELIMIT];//发车时间char C_ANAME[SIZELIMIT];//起点站char C_BNAME[SIZELIMIT];//终点站char C_USETIME[SIZELIMIT];//行车时间char C_MAXNUM[SIZELIMIT];//额定载量char C_REMAINNUM[SIZELIMIT];//余票数量}CardBase;int cbNum=0;//记录班次数CardBase cBList[MAXNUM];//班次列表//读取班次信息void readcardbasefile(){FILE *fp;//打开文件失败则创建文件if((fp=fopen("./number.dat","r"))==NULL){//初次运行创建文件if ((fp=fopen("./number.dat","w"))==NULL){exit(0); //返回}else{fclose(fp);}return ;}fseek(fp,0,2);//重定位文件内部位置指针/* int fseek( FILE *stream, long offset, int origin );第一个参数stream为文件指针第二个参数offset为偏移量,正数表示正向偏移,负数表示负向偏移第三个参数origin设定从文件的哪里开始偏移,可能取值为:SEEK_CUR、 SEEK_END 或 SEEK_SETSEEK_SET: 文件开头SEEK_CUR: 当前位置SEEK_END: 文件结尾其中SEEK_SET,SEEK_CUR和SEEK_END依次为0,1和2.简言之:fseek(fp,100L,0);把stream指针移动到离文件开头100字节处;fseek(fp,100L,1);把stream指针移动到离文件当前位置100字节处;fseek(fp,-100L,2);把stream指针退回到离文件结尾100字节处。 */if (ftell(fp)>0)//文件不为空{//文件位置指针移动到文件开始rewind(fp);char buff[10]={0};for (cbNum=0;!feof(fp) && fread(&cBList[cbNum],sizeof(CardBase),1,fp);cbNum++)fgets(buff,10,fp);/*char *fgets(char *buf, int bufsize, FILE *stream);从文件结构体指针stream中读取数据,每次读取一行。读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋'\0'),如果文件中的该行,不足bufsize个字符,则读完该行就结束。如若该行(包括最后一个换行符)的字符数超过bufsize-1,则fgets只返回一个不完整的行,但是,缓冲区总是以NULL字符结尾,对fgets的下一次调用会继续读该行。函数成功将返回buf,失败或读到文件结尾返回NULL。因此我们不能直接通过fgets的返回值来判断函数是否是出错而终止的,应该借助feof函数或者ferror函数来判断。*/fclose(fp);}else{fclose(fp);}return;}//保存班次信息void writecardbasefile(){int i;FILE *fp;if ((fp=fopen("./number.dat","w"))==NULL){printf("系统错误");}char buff[10]={0};strcpy(buff,"\r\n");for (i=0;i<cbNum;i++){if (fwrite(&cBList[i],sizeof(CardBase),1,fp)!=1){printf("系统错误");}if (fwrite(buff,2,1,fp)!=1){printf("系统错误");}}fclose(fp);}//保存排序信息void writesortfile(){int i;FILE *fp;if ((fp=fopen("./sort.dat","w"))==NULL){printf("系统错误");}char buff[10]={0};strcpy(buff,"\r\n");for (i=0;i<cbNum;i++){if (fwrite(&cBList[i],sizeof(CardBase),1,fp)!=1){printf("系统错误");}if (fwrite(buff,2,1,fp)!=1){printf("系统错误");}}fclose(fp);}//打印并输入后返回void printReturn(char *info){printf("\n\n\t %s",info);fflush(stdin);//清空输入缓冲区,通常是为了确保不影响后面的数据读取.getchar();}//输入信息void setInfo(char pinfo[1024],char desinfo[]){printf("\n\t%s:",pinfo);fflush(stdin);scanf("%s",desinfo);}//系统初始化void initsystem(){readcardbasefile();};//录入班次void infoinput(){setInfo("班次",cBList[cbNum].C_ID);setInfo("发车时间(24小时制)",cBList[cbNum].C_TIME);setInfo("起点站",cBList[cbNum].C_ANAME);setInfo("终点站",cBList[cbNum].C_BNAME);setInfo("行车时间",cBList[cbNum].C_USETIME);setInfo("额定载量",cBList[cbNum].C_MAXNUM);setInfo("余票数量",cBList[cbNum].C_REMAINNUM);cbNum++;writecardbasefile();printReturn("\n\t录入成功,回车键返回");};//时间比较int timecmp(char A[10]){//将火车时间转成整数char tempa[10]={0};int ta=0;int i;for(i=0;i<strlen(A);i++)if(A[i]!=':'&&A[i]!=':') //冒号的中文输入和英文输入{tempa[ta]=A[i];ta++;}int atime=atoi(tempa);//把字符串变成整型//获取系统时间char tempb[10]={0};time_t t = time(0);strftime( tempb, 10, "%H%M",localtime(&t) );int btime=atoi(tempb);//比较if(atime<=btime) //已经发车return 1;if(((atime-btime<=30)&&(atime-btime>5)&&(atime/100==btime/100))||(((atime%100+(60-btime%100))<=30)&&(atime%100+(60-btime%100))>5&&(atime/100-btime/100==1))) //距发车半小时以内,停止退票,%表示取余return 2;if(((atime-btime<=5)&&(atime/100==btime/100))||((atime%100+(60-btime%100)&&(atime/100-btime/100==1))<=5)) //距发车前五分钟内停止检票return 3;return 0; //可以办理购退票}//浏览所有班次void queryallinfo(){printf("班次信息\n");printf("班次 发车时间 起点站 终点站 行车时间 额定载量 余票数量 状态\n");int i;for(i=0;i<cbNum;i++){char temp[20]={0};strcpy(temp,"未发车");if(1==timecmp(cBList[i].C_TIME))strcpy(temp,"已发车");if(2==timecmp(cBList[i].C_TIME))strcpy(temp,"停止退票");if(3==timecmp(cBList[i].C_TIME))strcpy(temp,"停止检票");printf("%-010s%-010s%-010s%-010s%-010s%-010s%-010s%s\n",cBList[i].C_ID,cBList[i].C_TIME,cBList[i].C_ANAME,cBList[i].C_BNAME,cBList[i].C_USETIME,cBList[i].C_MAXNUM,cBList[i].C_REMAINNUM,temp );}printReturn("\n\t回车键返回");};//通过班次号查路线void queryinfobyID(){char ID[20]={0};setInfo("输入班次号",ID);int i;for( i=0;i<cbNum;i++){if(strcmp(cBList[i].C_ID,ID)==0){printf("班次信息\n");printf("班次 发车时间 起点站 终点站 行车时间 额定载量 余票数量\n");printf("%-010s%-010s%-010s%-010s%-010s%-010s%-010s\n",cBList[i].C_ID,cBList[i].C_TIME,cBList[i].C_ANAME,cBList[i].C_BNAME,cBList[i].C_USETIME,cBList[i].C_MAXNUM,cBList[i].C_REMAINNUM );printReturn("\n\t回车键返回");return;}}printReturn("\n\t指定信息不存在,回车键返回");};//通过终点站查路线void queryinfobyBNAME(){char Name[20]={0};setInfo("输入终点站",Name);int i;for(i=0;i<cbNum;i++){if(strcmp(cBList[i].C_BNAME,Name)==0){printf("班次信息\n");printf("班次 发车时间 起点站 终点站 行车时间 额定载量 余票数量\n");printf("%-010s%-010s%-010s%-010s%-010s%-010s%-010s\n",cBList[i].C_ID,cBList[i].C_TIME,cBList[i].C_ANAME,cBList[i].C_BNAME,cBList[i].C_USETIME,cBList[i].C_MAXNUM,cBList[i].C_REMAINNUM );printReturn("\n\t回车键返回");return;}}printReturn("\n\t指定信息不存在,回车键返回");};//排序按余票数量排序保存void sortSave(){//冒泡排序int i,j;for(i=0;i<cbNum;i++)for(j=0;j<cbNum-i-1;j++){if(atoi(cBList[j].C_REMAINNUM)<atoi(cBList[j+1].C_REMAINNUM)){CardBase temp=cBList[j];cBList[j]=cBList[j+1];cBList[j+1]=temp;}}//打印排序结果queryallinfo();//保存排序结果writesortfile();};//售票void sale(){char ID[20]={0};setInfo("输入班次号",ID);int i;for(i=0;i<cbNum;i++){if(strcmp(cBList[i].C_ID,ID)==0){if(cBList[i].C_REMAINNUM==0){printReturn("\n\t余票不足,回车返回");return;}//余票减少int temp=atoi(cBList[i].C_REMAINNUM)-1;if(temp<0) temp=0;//确保余票不为负数_itoa(temp,cBList[i].C_REMAINNUM,10);//保存到文件writecardbasefile();printf("班次信息\n");printf("班次 发车时间 起点站 终点站 行车时间 额定载量 余票数量\n");printf("%-010s%-010s%-010s%-010s%-010s%-010s%-010s\n",cBList[i].C_ID,cBList[i].C_TIME,cBList[i].C_ANAME,cBList[i].C_BNAME,cBList[i].C_USETIME,cBList[i].C_MAXNUM,cBList[i].C_REMAINNUM );printReturn("\n\t售票成功,回车返回");return;}}printReturn("\n\t指定班次不存在,回车键返回");};//退票void back(){char ID[20]={0};setInfo("输入班次号",ID);int i;for(i=0;i<cbNum;i++){if(strcmp(cBList[i].C_ID,ID)==0){//余票增加int temp=atoi(cBList[i].C_REMAINNUM)+1;_itoa(temp,cBList[i].C_REMAINNUM,10);//保存到文件writecardbasefile();printf("班次信息\n");printf("班次 发车时间 起点站 终点站 行车时间 额定载量 余票数量\n");printf("%-010s%-010s%-010s%-010s%-010s%-010s%-010s\n",cBList[i].C_ID,cBList[i].C_TIME,cBList[i].C_ANAME,cBList[i].C_BNAME,cBList[i].C_USETIME,cBList[i].C_MAXNUM,cBList[i].C_REMAINNUM );printReturn("\n\t\t退票成功,回车返回");return;}}printReturn("\n\t指定班次不存在,回车键返回");};//更新车次信息void update(){int flag;char ID[20]={0};setInfo("请输入要删除或修改的车次(请确认车次输入正确)",ID);do{printf("\n\t按下列提示更新车次信息(退出修改请按0):");printf("\n\t1:删除车次;2:修改发车时间;3:修改起点站;4:修改终点站;");printf("\n\t5:修改行车时间;6:修改额定载量;7:修改余票数量;0:退出修改;");printf("\n\t请选择:");scanf("%d",&flag);int i;CardBase temp;for(i=0;i<cbNum;i++){if(strcmp(cBList[i].C_ID,ID)==0){if(flag==1) //删除车次信息{int j;for(j=i;j<cbNum;j++)cBList[j]=cBList[j+1];//后面的数据覆盖前面的数据cbNum--;//车次数减一//保存到文件writecardbasefile();}if(flag==2) //修改发车时间{setInfo("请输入新的发车时间",cBList[i].C_TIME);temp=cBList[i];//保存到文件writecardbasefile();}if(flag==3) //修改起点站{setInfo("请输入新的起点站",cBList[i].C_ANAME);temp=cBList[i];//保存到文件writecardbasefile();}if(flag==4) //修改终点站{setInfo("请输入新的终点站",cBList[i].C_BNAME);temp=cBList[i];//保存到文件writecardbasefile();}if(flag==5) //修改行车时间{setInfo("请输入新的行车时间",cBList[i].C_USETIME);temp=cBList[i];//保存到文件writecardbasefile();}if(flag==6) //修改额定载量{setInfo("请输入新的额定载量",cBList[i].C_MAXNUM);temp=cBList[i];//保存到文件writecardbasefile();}if(flag==7) //修改余票数量{setInfo("请输入新的余票数量",cBList[i].C_REMAINNUM);temp=cBList[i];//保存到文件writecardbasefile();}}}//更改完成后显示更新后的班次信息,如果是删除车次则不显示,即flag不等于0的时候显示更新信息if(flag!=1&&flag!=0){ printf("更新后的班次信息\n");printf("班次 发车时间 起点站 终点站 行车时间 额定载量 余票数量\n");printf("%-010s%-010s%-010s%-010s%-010s%-010s%-010s\n",temp.C_ID,temp.C_TIME,temp.C_ANAME,temp.C_BNAME,temp.C_USETIME,temp.C_MAXNUM,temp.C_REMAINNUM );}}while(flag);printReturn("\n\t完成车次信息更新,回车键返回");};void mainmenu(){while(1){char select;do{system("cls");//清屏printf("\n\t ╭═════════■□■□═══╮");printf("\n\t│ 火车班次系统 │");printf("\n\t╰═══■□■□══════════╯");printf("\n\t ┌────────────────┐");printf("\n\t │1.录入班次 │");printf("\n\t │2.浏览所有班次 │");printf("\n\t │3.通过班次号查路线 │");printf("\n\t │4.通过终点站查路线 │");printf("\n\t │5.排序保存 │");printf("\n\t │6.售票 │");printf("\n\t │7.退票 │");printf("\n\t │8.更新车次信息 │");printf("\n\t │0.退出登录 │");printf("\n\t └────────────────┘");printf("\n\t 请选择:");fflush(stdin);//清空输入缓冲区,通常是为了确保不影响后面的数据读取.select=getchar();//等待用户输入数据}while (select<'0'||select>'8');switch(select){case '0':exit(0);break;case '1':infoinput();break;case '2':queryallinfo();break;case '3':queryinfobyID();break;case '4':queryinfobyBNAME();break;case '5':sortSave();break;case '6':sale();break;case '7':back();break;case '8':update();break;}}}//主函数int main(){initsystem(); //系统初始化while(1){mainmenu();}}程序中肯定还存在很多问题,自己对调用系统函数方面还有很多需要学习,文件的操作也不是很熟练,欢迎大家一起探讨交流。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例为大家分享了C语言实现航班管理系统的具体代码,供大家参考,具体内容如下#include#include#
本文实例讲述了基于C语言实现的迷宫算法。分享给大家供大家参考,具体如下:利用c语言实现迷宫算法,环境是vc++6.0.#include#include#incl
注册12306账号的用户可以将账号注销,但是,网上和客服是无法办理注销的,用户只能拿着自己的二代居民身份证到火车站售票窗口办理注销手续。也可以按12306网上订
C语言数据结构实现字符串分割的实例以下为“字符串分割”的简单示例:1.用c语言实现的版本#includeintpartition(ch
C语言数据结构之使用链表模拟栈的实例以下是“使用链表模拟栈”的简单示例:1.用C语言实现的版本#include#includetypedefchardataty