C语言课程设计 - 火车票预订系统

(考完再来更新。。。)o(╥ - ╥)o

文件介绍

在这里插入图片描述

mymac.h文件:
main.c文件:
只有一个入口函数 main(),实现两个功能:

  • ① 初始化:
    初始化3个全局变量;初始化用户信息(一定要有管理员)和列车信息,即在数据库中增加几条Person表和Train表的记录
  • ② 进入系统的交互界面并控制页面跳转:
    从3个界面中的主界面进入,由此开始在3个界面中切换

database.c文件:
mainWindow.c文件:
manager.c文件:
user.c文件:

代码

仅展示框架图中的代码结构,完整代码访问 github (还没传完。。。)

main.c(全)
#include "mymac.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>

int user_num;     // 当前用户登录状态
int manager_num;  // 当前管理员登录状态
int seed_adj;     // 随机种子调节因子

int main()
{
    /**  1.初始化 **/
    printf("初始化中,请稍后...\n");

    user_num = 0;
    manager_num = 0;
    seed_adj = 0;

    initialTrain();         // 火车x4
    initialPerson();        // 乘客x3 管理员x1

    system("cls");

    // 避免多次跳转页面程序嵌套,由主程序控制页面跳转
    /** 2.从主界面开始进入交互界面 控制页面跳转**/
    int forw = -1; // 是否发生页面跳转
    forw = mainMenu();
    while(1){
        if(forw == 0){
            forw = mainMenu();   //跳转到主界面
        }if(forw == 1){
            forw = userMenu();   //跳转到用户界面
        }else if(forw == 2){
            forw = managerMenu();   //跳转到管理员界面
        }else{
            break;
        }
    }

    return 0;
}
mymac.h(全)

/************************** 常用数值 *************************/
#ifndef PERSON_MAX
#define PERSON_MAX 100			//数据库中乘客记录不超过100
#endif

#ifndef TRAIN_MAX
#define TRAIN_MAX 20			//数据库中火车记录不超过20
#endif

#ifndef TICKIT_MAX
#define TICKIT_MAX 100			//数据库中购票记录不超过100
#endif

#ifndef STATION_LENGTH_MAX
#define STATION_LENGTH_MAX 40	//一辆火车总站点数不大于40字节
#endif

#ifndef NAME_LENGTH_MAX
#define NAME_LENGTH_MAX 30		//名字(站点名或人名)不大于30字节
#endif

#ifndef ID_LENGTH_MAX
#define ID_LENGTH_MAX 19		//身份证不大于18字节
#endif

#ifndef GENDER_LENGTH_MAX
#define GENDER_LENGTH_MAX 4		//性别 不大于4字节
#endif

#ifndef TEL_LENGTH_MAX
#define TEL_LENGTH_MAX 12      //电话不大于11字节
#endif

#ifndef CODE_LENGTH_MAX
#define CODE_LENGTH_MAX 7   	//密码 不大于6字节
#endif

#ifndef SET_SEED
#define SET_SEED srand(time(NULL)+seed_adj++)  	//密码 不大于6字节
#endif

/************************** 带参数宏 *************************/

// 命令提示语句
#ifndef COMMAND
#define COMMAND(s) color(2); printf(s); printf(">> "); color(15);
#endif

// 标题
#ifndef TITLE
#define TITLE(s) color(6); printf(s); color(15);
#endif

// 提示信息
#ifndef HINT
#define HINT(s) color(3); printf(s); color(15);
#endif

/************************** Person, Tickit, Train 3种结构体 *************************/
typedef struct _Person
{
	int person_num;			//乘客编号-主键
	char person_name[NAME_LENGTH_MAX];	//乘客姓名
	char id[ID_LENGTH_MAX];			//18位身份证号
	char gender[GENDER_LENGTH_MAX];			//性别
	char tel[TEL_LENGTH_MAX];			//号码,最多11位
	char code[CODE_LENGTH_MAX];			//密码,最多6位
	struct _Person* next;	//便于链表操作
}Person;

typedef struct _Tickit
{
	int tickit_num;		//票号-主键
	int person_num;		//用户编号
	int train_num;		//火车编号
//	int seat_num;		//座位号

	int start;			//起点站号
	int end;			//终点站号
	double price;			//票价

	struct _Tickit* next;		//便于链表操作
}Tickit;

typedef struct _Train
{
	int train_num;				//火车编号
	int sta_count;				//总站点数,不大于30
    char train_name[NAME_LENGTH_MAX]; //火车名
	char sta_name[STATION_LENGTH_MAX][NAME_LENGTH_MAX];		//站点名称
	double adj_sta_price[STATION_LENGTH_MAX];	//相邻2站之间的票价
	int adj_tic_num[STATION_LENGTH_MAX];		//相邻2站之间的余票,初始值200
	struct _Train* next;				//便于链表操作
}Train;

database.c(不全)

太长不贴了,仅展示person表增删改查部分,大同小异

#include "mymac.h"
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

extern int manager_num;
extern int user_num;
extern int seed_adj;

/************************** 对Person表的增删改查 *************************/
/*
	新增乘客信息
	遍历文件查看 身份证号 是否已经存在
		不存在则在文件末尾插入新乘客信息,在文件尾操作因此不需要存入链表
		存在则返回新增失败
*/
int addPerson(char * person_name, char* id, char* gender, char* tel, char* code)
{
	//打开person文件; 任何地方判断出错则返回false
	FILE* fp = fopen("person.txt", "ab+"); // a+可读可写
	if (fp == NULL) {
		return 0;	//非0即true
	}
	Person person;	// 缓冲区
	// 乘客信息不能相同 检查是否已经存在-> 存在则不用增加
	while (!feof(fp)) {
		if (fread(&person, sizeof(Person), 1, fp) != 0) {

			if (strcmp(person.id, id) == 0) { //身份证号相同
				printf("乘客信息已存在\n");
				fclose(fp);
				return 0;	// 乘客信息已存在

			}
		}
		else {
//			printf("fread读取为0\n");
		}
	}

	//乘客不存在,新增乘客信息
	//新增Person
	SET_SEED;
	person.person_num = rand();
	strcpy(person.person_name, person_name);
	strcpy(person.id, id);
	strcpy(person.gender, gender);
	strcpy(person.tel, tel);
	strcpy(person.code, code);

	//在文件末尾写入Person节点
	fseek(fp, 0, SEEK_END);
	fwrite(&person, sizeof(Person), 1, fp);

	fclose(fp);
	return 1;
}

/*
	删除一个乘客信息
	同时对tickit表进行对应更改
	输入:乘客编号 或者 乘客id

	遍历文件,查看乘客是否存在
		在文件中间进行操作,因此将所有数据存入动态链表
		存在,则删除节点 tag = 1
		不存在,则无操作 tag =0
*/
int delPerson(int person_num)
{
	//打开person文件; 覆盖式写入; 任何地方判断出错则返回false
	FILE* fp = fopen("person.txt", "rb");
	if (fp == NULL) {
		return 0;	//非0即true
	}
	Person person_buff;
	Person* L, * p;
	int tag = 0;	// 找到目标节点tag为1

	L = (Person*)malloc(sizeof(Person));
	L->next = NULL;

	while (!feof(fp)) {
        if(fread(&person_buff, sizeof(Person), 1, fp) > 0){
//            printf("\n 本次比对 buff_num=%d, person_num=%d\n\n", person_buff.person_num, person_num);
            if (person_buff.person_num == person_num) {
                tag = 1; //目标节点不读出
            }
            else {
                // 新增结点
                p = (Person*)malloc(sizeof(Person));
                p->person_num = person_buff.person_num;
                strcpy(p->id, person_buff.id);
                strcpy(p->person_name, person_buff.person_name);
                strcpy(p->gender, person_buff.gender);
                strcpy(p->tel, person_buff.tel);
                strcpy(p->code, person_buff.code);
                // 插入链表;减少一个指针,使用头插法
                p->next = L->next;
                L->next = p;
            }

        }else{
                break;
			}

	}
    fclose(fp);

	if (tag == 1) { //删除目标节点
//		if (delTickit(2, person_num)) {	//更新Tickit表成功的前提下,更新Person表
            delTickit(2, person_num);
            //覆盖式打开文件
            FILE* fp = fopen("person.txt", "wb");
            if (fp == NULL) {
                return 0;	//非0即true
            }
            // 文件头
			fseek(fp, 0, SEEK_SET);
			p = L->next;
			while (p) {
				fwrite(p, sizeof(Person), 1, fp);
				p = p->next;
			}
            // 关闭文件
			fclose(fp);
			return 1;
	}

	free(p);
	return 0;

}

/*
	更新一个乘客信息
	只能更新 号码 密码 2项
		char tel[12];			//号码,最多11位
		char code[7];			//密码,最多6位
*/
int updPerson(int person_num, int op)
{
	//打开person文件; 覆盖式写入; 任何地方判断出错则返回false
	FILE* fp = fopen("person.txt", "rb");
	if (fp == NULL) {
		printf("file open failure\n");
		return 0;	//非0即true
	}

	char* parastr;

	Person person_buff;
	Person* L, * p;
	int tag = 0;	// 更新成功tag为1

	L = (Person*)malloc(sizeof(Person));
	L->next = NULL;

	while (!feof(fp)) {
//		printf("finish2\n");

		if(fread(&person_buff, sizeof(Person), 1, fp) > 0){
            p = (Person*)malloc(sizeof(Person));
            if (person_buff.person_num == person_num) {
                if (tag == 0 && op == 1) {	// 更改电话
                    COMMAND("请输入新11位电话号码:");
                    parastr = (char*)malloc(sizeof(char) * 12);
                    scanf("%s", parastr);
                    if(strlen(parastr) != 11){
                        printf("格式错误\n");
                        break;
                    }
                    strcpy(p->tel, parastr);
                    strcpy(p->code, person_buff.code);
                    tag = 1;
                }
                else if (tag == 0 && op == 2) {          //更改密码
                    COMMAND("请输入新6位密码:");
                    parastr = (char*)malloc(sizeof(char) * 7);
                    scanf("%s", parastr);
                    if(strlen(parastr) != 6){
                        printf("格式错误\n");
                        break;
                    }
                    strcpy(p->tel, person_buff.tel);
                    strcpy(p->code, parastr);
                    tag = 1;
                }

            }
            else {
                strcpy(p->tel, person_buff.tel);
                strcpy(p->code, person_buff.code);
            }
            // 另4项不可改变
            p->person_num = person_buff.person_num;
            strcpy(p->person_name, person_buff.person_name);
            strcpy(p->id, person_buff.id);
            strcpy(p->gender, person_buff.gender);

            p->next = L->next;
            L->next = p;
            }else{
                break;
			}

	}

	fclose(fp);
	if (tag == 1) { //更新成功,将新的链表覆盖式写入文件
		// 打开文件
		fp = fopen("person.txt", "wb");
		if (fp == NULL) {
			return 0;	//非0即true
		}

		// 写入文件
		fseek(fp, 0, SEEK_SET);
		p = L->next;
		while (p) {
			fwrite(p, sizeof(Person), 1, fp);
			p = p->next;
		}

		// 关闭文件
		fclose(fp);

		return 1;
	}
	else {// 更新失败,不写回文件
		return 0;
	}


}

/*
*   仅管理员有此权限
*	4种查询方式
	int person_num;			//乘客编号-主键
	char person_name[20];	//乘客姓名
	char id[19];			//18位身份证号
	char tel[12];			//号码,最多11位
*/
int* qurPerson(int op)
{
	//打开person文件; 覆盖式写入; 任何地方判断出错则返回false
	FILE* fp = fopen("person.txt", "rb");
	if (fp == NULL) {
		return NULL;	//非0即true
	}
	int tag = 0;	// 查询成功tag=1
	int* person_nums = (int*)calloc(PERSON_MAX, sizeof(int)); //初始化为0
	int cur = 0;

	// 4种查询方式需键入的值
	int person_num = 0;			//乘客编号-主键
	char person_name[NAME_LENGTH_MAX];	//乘客姓名
	char id[ID_LENGTH_MAX];			//18位身份证号
	char tel[TEL_LENGTH_MAX];			//号码,最多11位

	Person* p = (Person*)malloc(sizeof(Person));

	// 根据不同方式定位结点
	switch (op) {
	case 1: /*根据乘客编号查询*/
	    COMMAND("请输入待查询的乘客编号")
		scanf("%d", &person_num);
		while (!feof(fp)) {
			if(fread(p, sizeof(Person), 1, fp) > 0){
                if (p->person_num == person_num) {
                    person_nums[cur++] = p->person_num;
                    tag = 1;
                    break;
                }
			}else{
                break;
			}

		}
		break;

	case 2: /*根据姓名查询*/
	    COMMAND("请输入待查询的乘客姓名")
		scanf("%s", person_name);
		while (!feof(fp)) {
			if(fread(p, sizeof(Person), 1, fp) > 0){
                if(strcmp(p->person_name, person_name) ==0){
                person_nums[cur++] = p->person_num;
				tag = 1;
                }
			}else{
                break;
			}
		}
		break;
	case 3: /*根据身份证查询*/
		COMMAND("请输入待查询的乘客身份证件号码");
		scanf("%s", id);
		while (!feof(fp)) {
			if(fread(p, sizeof(Person), 1, fp) > 0){
                if (strcmp(p->id, id) == 0) {
                    person_nums[cur++] = p->person_num;
                    tag = 1;
                    break;
                }

			}else{
                break;
			}

		}
		break;
	case 4: /*根据手机号码查询*/
        COMMAND("请输入11位手机号");
		scanf("%s", tel);
        while (!feof(fp)) {
            if(fread(p, sizeof(Person), 1, fp) > 0){
                if (strcmp(p->tel, tel) == 0) {
                    person_nums[cur++] = p->person_num;
                    tag = 1;
                    break;
                }
            }else{
                break;
            }

        }

		break;
	default:
		break;
	}

	fclose(fp);

	if (tag == 1) {
		return person_nums;
	}
	return NULL;
}

mainWindow.c (全)
#include "mymac.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>

extern int user_num;
extern int manager_num;
extern int seed_adj;   // 随机种子调节因子

void color(short x) //自定义函根据参数改变颜色
{
	if (x >= 0 && x <= 15)//参数在0-15的范围颜色
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x); //只有一个参数,改变字体颜色
	else//默认的颜色白色
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}

void exitInter()
{
    HINT("\n\n已退出,感谢使用!\n\n");
    system("pause");
    exit(-1);
}

/*
  主界面
*/
int mainMenu()
{
    system("cls");

    HINT("\n欢迎使用火车预定系统!\n");
//	printf("this is the function of making mainmenu\n");
    printf("****************************************************\n");
    printf("***                  ");TITLE("系统主页");printf("                    ***\n");
    printf("****************************************************\n");
    printf("\n》主界面》\n");
    printf("****************************************************\n");
    printf("*                   0.退出                         *\n");
    printf("*                   1.用户模式                     *\n");
    printf("*                   2.管理员模式                   *\n");
    printf("****************************************************\n\n");

	int forw = -1;
	while(1){
        COMMAND("请输入数字选择【模式操作】");
        scanf("%d", &forw);
        if(forw == 0){
            exitInter();
            break;
        }else if(forw == 1 || forw == 2){
            break;
        }else{
            printf("无相应操作数字,请重试\n\n");
        }
	}

	return forw;
}

user.c (不全)

仅展示主要函数 ==int userMenu() ==

#include "mymac.h"
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

extern int manager_num;
extern int user_num;
extern int seed_adj;


/*
  用户界面
*/
int userMenu()
{
    system("cls");
    int forw = -1;

    if(user_num == 0){ //无登录状态,需要先登录
        printf("****************************************************\n");
        printf("***                    ");TITLE("用户模式");printf("                  ***\n");
        printf("****************************************************\n");

        int opr;
        // 合法登录才能使用功能
        HINT("您需要登录账号来使用系统(无账号请先注册)\n\n")
        while(1){
            printf("\n》主界面》用户模式》用户登录\n");
            printf("****************************************************\n");
            printf("*                   0.返回主界面                   *\n");
            printf("*                   1.登录                         *\n");
            printf("*                   2.注册                         *\n");
            printf("****************************************************\n\n");
            COMMAND("请输入数字选择【登录操作】");
            scanf("%d", &opr);
            if(opr == 0){
                return 0; //跳转主界面
            }else if(opr == 1){
                signIn();
                break;
            }else if(opr == 2){
                signUp();
                break;
            }else{
                printf("无相应操作数字,请重试\n\n");
            }
        }

    }


	// 进行操作
	system("cls");
	Person *p = getPerson(user_num);
	HINT("\n欢迎用户");TITLE(p->person_name);
	HINT("! 您的系统编号是");printf("%d\n", p->person_num);
    printf("******************************************************************************************\n");
    printf("***                                      ");TITLE("用户模式");printf("                                      ***\n");
    printf("******************************************************************************************\n");
    int opr;
	while(1){
        printf("\n》主界面》用户模式》用户操作》\n");
        printf("******************************************************************************************\n");
        printf("*  0.返回主界面   1.账号设置       2.车次信息查询         3.购票和退改     4.我的主页    *\n");
        printf("*                   >注销账号        >根据车次编号查询      >购票            >我的资料   *\n");
        printf("*                   >更改密码        >根据车次名查询        >退票            >我的订单   *\n");
        printf("*                   >更改电话号码    >根据途径站点查询      >改签                        *\n");
        printf("*                                    >根据起点&终点查询                                  *\n");
        printf("*                                    >查看所有车次信息                                   *\n");
        printf("******************************************************************************************\n\n");

        COMMAND("请输入数字选择【用户操作】");
        scanf("%d", &opr);
        if(opr == 0){
            forw = 0;
            break;
        }else if(opr == 1){
            if(userAccount() == 1){
                forw = 0;
                break;
            }
        }else if(opr == 2){
            userQur();
        }else if(opr == 3){
            userTikOP();
        }else if(opr == 4){
            userPage();
        }else{
            printf("无相应操作数字,请重试\n\n");
        }
	}

	return forw;
}
manager.c(不全)

仅展示主要函数 managerMenu()

#include "mymac.h"
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

extern int manager_num;
extern int user_num;
extern int seed_adj;

/*
  管理员界面
*/
int managerMenu()
{
    system("cls");
    int forw = -1;

    if(manager_num == 0){ //无登录状态,需要先登录
        printf("****************************************************\n");
        printf("***                   ");TITLE("管理员模式");printf("                 ***\n");
        printf("****************************************************\n");

        int opr;
        // 合法登录才能使用功能
        HINT("您需要登录账号来使用系统\n\n");
        while(1){
            printf("\n》主界面》管理员模式》管理员登录\n");
            printf("****************************************************\n");
            printf("*                   0.返回主界面                   *\n");
            printf("*                   1.登录                         *\n");
            printf("****************************************************\n\n");
            COMMAND("请输入数字选择【登录操作】");
            scanf("%d", &opr);
            if(opr == 0){
                return 0; //跳转主界面
            }else if(opr == 1){
                signInMana();
                break;
            }else{
                printf("无相应操作数字,请重试\n\n");
            }
        }

    }


	// 登录成功,操作
	system("cls");
	Person *p = getPerson(manager_num);
	HINT("\n欢迎管理员");TITLE(p->person_name);
	HINT("! 您的系统编号是");printf("%d\n", p->person_num);
    printf("*************************************************************************************************************\n");
    printf("***                                              ");TITLE("管理员模式");printf("                                               ***\n");
    printf("*************************************************************************************************************\n");
    int opr;
	while(1){
        printf("\n》主界面》管理员模式》管理员操作》\n");
        printf("*************************************************************************************************************\n");
        printf("*  0.返回主界面  1.账号设置       2.车次管理           3.用户管理           4.票务管理           5.我的主页 *\n");
        printf("*                  >更改密码        >根据火车编号查看    >根据用户编号查看    >根据车票编号查看    >我的资料*\n");
        printf("*                  >更改电话号码    >根据车次名查看      >根据用户名查看      >根据用户编号查看             *\n");
        printf("*                                   >根据途径站点查看    >查看所有用户信息    >根据火车编号查看             *\n");
        printf("*                                   >根据起点&终点查看                        >查看所有车票信息             *\n");
        printf("*                                   >查看所有车次信息                                                       *\n");
        printf("*                                   >增设车次                                                               *\n");
        printf("*                                   >删除车次                                                               *\n");
        printf("*************************************************************************************************************\n\n");

        COMMAND("请输入数字选择【管理员操作】");
        scanf("%d", &opr);
        if(opr == 0){
            forw = 0;
            break;
        }else if(opr == 1){
            manaAccount();
        }else if(opr == 2){
            manaTrainOP();
        }else if(opr == 3){
            manaUserOP();
        }else if(opr == 4){
            manaTickitOP();
        }else if(opr == 5){
            manaPage();
        }else{
            printf("无相应操作数字,请重试\n\n");
        }
	}

	return forw;
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值