Makefile多文件统筹开发,标准io实现用户注册,登录,密码星号保密打印,管理员在注册登录界面直接输(1443003064): 实现对航班的增删改查;用户:实现对航班信息的总览,查询机票,订票,退票, 查看个人订单。
可以直接cp用作数据结构课设还是可以的,如果文件操作没有学,可以自己把账号跟密码放入链表数据里。
.h文件
#ifndef __FLIGHT_H__
#define __FLIGHT_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <stdbool.h>
#include <termio.h>
typedef struct flight_data //航班信息数据结构
{
int flightID; //航班号(月日时分+当日起飞次序)
char staaddress[20]; //起点站
char arraddress[20]; //终点站
char plane[20]; //机型
char stime[20]; //起飞时间(月日时分)
char atime[20]; //到达时间(月日时分)
int value; //票价
int ticket; //飞机票数
} flight, *pflight;
typedef struct node //双向链表结点
{
flight data;
struct node *next;
struct node *prev;
} node, *pnode;
typedef struct JiaJieMi
{
char id[11]; // id 即登录的账号
char pwd[20]; //密码
} decrypt; //用来账号和伪密码联系起来,存入另一个一个文件;
typedef struct Userinfo
{
char userid[11]; // id 即登录的账号
char pwd[20]; //密码
char username[15]; //姓名
char userphone[12]; //电话
} user, *puser; // 用户信息
node *create_Init(); //创建头节点并初始化
void node_insert_end(node *head); //添加航班(管理员)
void delete_flight(node *head); //删除航班信息(adm)
void show_flight(node *head); //查看航班信息(adm,user)
void updata_time(node *head); //修改航班信息,晚点时使用(管理员)
bool find_flight(node *head); //搜索航班信息(管理员和用户通用)
int book_flight(node *head); //订票(用户)
void refund_ticket(node *head, int x); //退票(user)
void show_ticket(node *head, int x);//查看个人订票
void admmenu(node *head); //(管理员菜单界面)
void common_usermenu(node *head); //普通用户菜单界面
void main_UI();//初始化界面
int getch(void);//vim终端设置
void regis();//注册
void login(node *head); //登录
#endif
.c文件
#include "flight.h"
int RETU = 0; //定义全局变量为订票功能服务,返回值,注意此变量名不能与函数形参名相同,否则只会修改形参
node *create_Init() //创建头节点并初始化
{
node *phead = (node *)malloc(sizeof(node));
if (NULL == phead)
{
printf("头节点申请错误\n");
return NULL;
}
phead->next = phead; //定义成双向循环链表
phead->prev = phead;
return phead;
}
void node_insert_end(node *head) //添加航班(管理员)
{
node *pnew = (node *)malloc(sizeof(node)); //申请内存,创建新节点
if (pnew == NULL) //容错处理
{
printf("申请失败!");
}
if (head != NULL)
{
head->prev->next = pnew; //链接新节点
pnew->prev = head->prev;
head->prev = pnew;
pnew->next = head;
printf("\n航班号:");
scanf("%d", &pnew->data.flightID);
printf("\n起点站:");
scanf("%s", pnew->data.staaddress);
printf("\n终点站:");
scanf("%s", pnew->data.arraddress);
printf("\n机型:");
scanf("%s", pnew->data.plane);
printf("\n起飞时间:");
scanf("%s", pnew->data.stime);
printf("\n到达时间:");
scanf("%s", pnew->data.atime);
printf("\n票价:");
scanf("%d", &pnew->data.value);
printf("\n票数:");
scanf("%d", &pnew->data.ticket);
printf("\n添加完成\n");
printf("\t\t\t\t\t****************************************************************^-^\n\n\n\n\n\n");
}
}
void delete_flight(node *head) //删除航班信息(adm)
{
if (head == NULL) //容错处理
{
printf("传入失败!");
}
node *ptemp = head; //定义临时节点
int id;
printf("请输入要删除的航班ID^-^:");
scanf("%d", &id);
do
{
ptemp = ptemp->next;
if (id == ptemp->data.flightID)
{
ptemp->prev->next = ptemp->next; //链接与断开
ptemp->next->prev = ptemp->prev;
printf("\n\n删除成功!");
free(ptemp); //释放内存并置空
ptemp = NULL;
return;
}
} while (ptemp != head); //遍历寻找id
printf("未找到此ID,请检查是否输入错误!^-^\n"); //在循环内未找到,输出这句话
}
void show_flight(node *head) //查看航班信息(adm,user)
{
if (head == NULL) //容错处理
{
printf("传入失败!");
}
node *ptemp = head; //临时节点遍历
printf("\n\n\n\n\n\n\t\t\t\t\t航班号 起点站 终点站 机型 起飞时间 到达时间 票价 票数^-^\n\n");
do
{
ptemp = ptemp->next;
printf("\t\t\t\t\t%d %s %s %s %s %s %d %d\n", ptemp->data.flightID, ptemp->data.staaddress,
ptemp->data.arraddress, ptemp->data.plane, ptemp->data.stime, ptemp->data.atime, ptemp->data.value, ptemp->data.ticket);
} while (ptemp != head);
printf("\n\t\t\t\t\t**********************************^-^******************************\n\n\n\n\n\n\n\n\n\n");
}
void updata_time(node *head) //修改航班信息,晚点时使用(管理员)
{
if (head == NULL) //容错处理
{
printf("传入失败!");
}
node *ptemp = head; //定义临时节点,遍历
int id;
char time[20]; //延误后的时间
printf("\n请输入要修改的航班ID^-^:");
scanf("%d", &id);
do
{
ptemp = ptemp->next;
if (id == ptemp->data.flightID)
{
printf("\n请输入延误后时间^-^\n");
scanf("%s", time);
strcpy(ptemp->data.atime, time);
printf("\n修改成功!^-^\n\n\n\n\n");
return;
}
} while (ptemp != head);
printf("\n\n未找到此ID,请检查是否输入错误!^-^\n\n\n\n\n");
}
bool find_flight(node *head) //搜索航班信息(管理员和用户通用)运用起点站和目的地查询
{
if (head == NULL) //容错处理
{
printf("传入失败!");
}
int t; //方便呈现比对结果
char arrive[20];
char start[20];
printf("\n请输入您当前的位置^-^\n");
scanf("%s", start);
printf("\n请输入您的目的地^-^\n");
scanf("%s", arrive);
printf("正在查询!\n正在显示!\n");
node *ptemp = head->next;
printf("\n\n\n\n\n\n\t\t\t\t\t航班号 起点站 终点站 机型 起飞时间 到达时间 票价 票数^-^\n\n");
while (ptemp != head)
{ //两次比对结果(位或),strcmp(a,b)a,b相同则为0;
t = !(strcmp(ptemp->data.staaddress, start) | strcmp(ptemp->data.arraddress, arrive));
if (t == 1)
{
printf("\t\t\t\t\t%d %s %s %s %s %s %d %d\n", ptemp->data.flightID, ptemp->data.staaddress,
ptemp->data.arraddress, ptemp->data.plane, ptemp->data.stime, ptemp->data.atime,
ptemp->data.value, ptemp->data.ticket);
}
ptemp = ptemp->next; //两次比对结果(位或),strcmp(a,b)a,b相同则为0;
}
printf("\n\n查询完成!^-^\n\n\n");
}
int book_flight(node *head) //订票(用户)
{
if (head == NULL) //容错处理
{
printf("\n传入失败!\n");
}
if (find_flight(head))
{
int t;
node *ptemp = head;
printf("请选择您想要乘坐的航班号^-^");
scanf("%d", &t);
do
{
ptemp = ptemp->next;
if (t == ptemp->data.flightID)
{
ptemp->data.ticket = ptemp->data.ticket - 1;
printf("\n\n\n\n\n\n\t\t\t\t\t航班号 起点站 终点站 机型 起飞时间 到达时间 票价 票数^-^\n\n");
printf("\t\t\t\t\t%d %s %s %s %s %s %d %d\n", ptemp->data.flightID, ptemp->data.staaddress,
ptemp->data.arraddress, ptemp->data.plane, ptemp->data.stime, ptemp->data.atime,
ptemp->data.value, ptemp->data.ticket);
printf("订购成功!^-^\n\n\n\n\n\n\n\n");
printf("\n\t\t\t\t\t*********************************^-^*********************************\n");
return ptemp->data.flightID;
}
} while (ptemp != head);
printf("\n\n输入错误的航班ID^-^\n\n\n\n\n\n\n");
}
}
void refund_ticket(node *head, int x) //退票(user)
{
if (head == NULL) //容错处理
{
printf("传入失败!");
}
if (head != NULL)
{
int r;
node *ptemp = head;
printf("\t请选择您想要退订的航班号^-^\n");
scanf("%d", &r);
do
{
ptemp = ptemp->next;
if (r == ptemp->data.flightID) //输入要退订航班号与订购的航班id比对
{
ptemp->data.ticket = ptemp->data.ticket + 1; //找到就加一,退回一张票
RETU = -1; // RETU 置为-1,在个人订单使用,用作比对
printf("退订成功!^-^\n\n\n\n");
return;
}
} while (ptemp != head);
printf("\t未订购此航班机票!^-^\n\n\n\n");
}
}
void show_ticket(node *head, int x) //查看个人订单
{
if (head == NULL) //容错处理
{
printf("传入失败!");
}
if (head != NULL)
{
node *ptemp = head;
do
{
ptemp = ptemp->next;
if (RETU == ptemp->data.flightID)
{
printf("\t\t\t\t\t************************ 个人 订单 *************************^-^\n");
printf("\n\t\t\t\t\t航班号 起点站 终点站 机型 起飞时间 到达时间 票价 票数^-^\n\n");
printf("\t\t\t\t\t%d %s %s %s %s %s %d %d\n", ptemp->data.flightID, ptemp->data.staaddress,
ptemp->data.arraddress, ptemp->data.plane, ptemp->data.stime, ptemp->data.atime,
ptemp->data.value, ptemp->data.ticket);
printf("\n\n\n\n\n");
return;
}
} while (ptemp != head);
printf("\n您还没有订单!\n\n\n\n\n");
}
}
void admmenu(node *head) //(管理员菜单界面)
{
if (head == NULL) //容错处理
{
printf("传入失败!");
}
printf("\033c");
char choose[20];
int flag = 1, ch;
while (flag)
{
printf("\n\n\n请输入你要进行的操作:^-^\n\n");
printf("\t\t\t\t\t************************ 管理员界面 *************************^-^\n");
printf("\t\t\t\t\t************************1.增加航班信息 ************************^-^\n");
printf("\t\t\t\t\t************************2.删除航班信息 ************************^-^\n");
printf("\t\t\t\t\t************************3.查看航班信息 ************************^-^\n");
printf("\t\t\t\t\t************************4.搜索航班信息 ************************^-^\n");
printf("\t\t\t\t\t************************5.修改航班信息 ************************^-^\n");
printf("\t\t\t\t\t************************0.退出管理员操作 **********************^-^\n");
scanf("%s", choose);
ch = atoi(choose); //防止输入字母时系统崩溃,用atoi转成整型
switch (ch)
{
case 1:
node_insert_end(head); //尾插法,增加航班
break;
case 2:
delete_flight(head); //删除航班
break;
case 3:
show_flight(head); //查看所有航班
break;
case 4:
find_flight(head); //查找航班根据起点与终点
break;
case 5:
updata_time(head); //修改时间
break;
case 0:
flag = 0; // 退出
break;
default:
printf("请输入正确的序号!\n");
break;
}
}
}
void common_usermenu(node *head) //普通用户菜单界面
{
if (head == NULL) //容错处理
{
printf("传入失败!");
}
int flag = 1, choo;
printf("\033c");
while (flag)
{
printf("\t\t\t\t\t\t ^-^ 欢迎使用航空订票系统 ^-^ \n");
printf("\t\t\t\t\t****xx航空公司将竭心为您服务,请选择您的需求选择服务,祝您使用愉快!*****^-^\n");
printf("\t\t\t\t\t*********************** 1.查看航班 *************************^-^\n");
printf("\t\t\t\t\t*********************** 2.搜索航班 *************************^-^\n");
printf("\t\t\t\t\t*********************** 3.订票 *************************^-^\n");
printf("\t\t\t\t\t*********************** 4.退票 *************************^-^\n");
printf("\t\t\t\t\t*********************** 5.查看个人订单 *************************^-^\n");
printf("\t\t\t\t\t*********************** 0.退出系统 *************************^-^\n");
printf("\n\t请输入你要进行的操作:^-^\n\n");
char choose[20];
scanf("%s", choose);
choo = atoi(choose);
switch (choo)
{
case 1:
show_flight(head);
break;
case 2:
find_flight(head);
break;
case 3:
RETU = book_flight(head);
break;
case 4:
refund_ticket(head, RETU);
break;
case 5:
show_ticket(head, RETU);
break;
case 0:
flag = 0;
printf("感谢您的使用!\n\n\n\n\n");
break;
default:
printf("请输入正确的序号!\n\n");
break;
}
}
}
void main_UI()
{
printf("\033c"); //清屏
printf("\n\n\n\n\n\n\n\n\n");
printf("\t\t\t\t\t ^-^ 欢迎使用xx航空订票系统 ^-^ \n");
printf("\t\t\t\t\t****xx航空公司将竭心为您服务,请选择您的需求选择服务,祝您使用愉快!*****^-^\n\n");
printf("\t\t\t\t\t************************* 1.注册 ***************************^-^\n");
printf("\t\t\t\t\t************************* 2.登录 ***************************^-^\n");
printf("\t\t\t\t\t*********************** 0.退出系统 ***************************^-^\n");
printf("\n\t\t请输入你要进行的操作:^-^\n\n");
}
int getch(void) // vim终端设置
{
struct termios tm, tm_old;
int fd = 0, ch;
if (tcgetattr(fd, &tm) < 0) //保存现在的终端设置
{
return -1;
}
tm_old = tm; //更改终端设置为原始模式,该模式下所有的输入数据以字节为单位被处理
cfmakeraw(&tm);
if (tcsetattr(fd, TCSANOW, &tm) < 0) //设置上更改之后的设置
{
return -1;
}
ch = getchar();
if (tcsetattr(fd, TCSANOW, &tm_old) < 0) //更改设置为最初的样子
{
return -1;
}
return ch;
}
void regis()
{
user a;
decrypt b;
char arr[20]; //输入的密码
char bb[20]; //加密处理后的密码
char c; //消除回车
printf("\033c");
printf("欢迎来到注册界面!\n");
FILE *pf = fopen("users.txt", "a");
if (pf == NULL)
{
perror("open失败");
return;
}
printf("请输入您的姓名>>");
scanf("%s", a.username);
printf("请输入您的电话号码>>");
scanf("%s", a.userphone);
printf("请输入您的帐号>>");
scanf("%s", a.userid);
printf("请输入您的密码(不超过20位)>>");
strcpy(a.pwd, "******");
fprintf(pf, "%s %s %s %s\n", a.userid, a.pwd, a.username, a.userphone);
fclose(pf);
pf == NULL;
c = getchar();
int i = 0;
int j = 0;
while (i < 20)
{
arr[i] = getch(); // getch()从控制台输入一各字符但是不显示
if (arr[i] == '\b' && i > 0) //遇到空格不管
{
continue;
}
if (arr[i] == '\b' && i == 0) //如果在最开始就按退格键(backspace),就让i=-1
{
i = 0;
continue;
}
if (arr[i] == '\r') //如果输入的是回车,就退出输入循环
{
break;
}
i++;
putchar('*');
}
arr[i] = '\0';
printf("\n");
for (int j = 0; j < strlen(arr); ++j)
{
bb[j] = arr[j] + j; //加密方法:用户密码+j后保存到文本;
}
bb[strlen(arr)] = '\0';
strcpy(b.id, a.userid);
strcpy(b.pwd, bb);
FILE *q = fopen("decrypt.txt", "a");
if (q == NULL)
{
perror("open<decrypt>失败");
return;
}
fprintf(q, "\n%s %s", b.id, b.pwd);
fclose(q);
q == NULL;
printf("\t注册成功!");
}
void login(node *head) //登录
{
if (head == NULL) //容错处理
{
printf("传入失败!");
}
char rr[20]; //输入的密码
decrypt a, b;
char c;
FILE *pf = fopen("decrypt.txt", "r");
if (pf == NULL)
{
perror("open<decrypt>失败");
return;
}
printf("\033c");
printf("\n\t\t欢迎来到登录界面!\n");
fscanf(pf, "%s %s", a.id, a.pwd);
printf("\t\t请输入账号>>");
scanf("%s", b.id);
c = getchar();
while (1)
{
if (!strcmp(a.id, b.id)) //在文件中找到了与用户输入相同的id
{
break;
}
else
{
if (!feof(pf)) //没读到文件末尾,继续读取文件中的id到a中
{
fscanf(pf, "%s %s", a.id, a.pwd); //继续从文件中读取用户信息进a,直到在文件中找到一个和a的信息相同的
}
else //读到文件末尾了,没有找到与用户输入相同的账号
{
printf("\n\t此账号不存在!请注册!\n");
fclose(pf);
pf = NULL;
regis();
return;
}
}
}
char d;
char mima[20]; //解密后的密码
char weimima[30]; //保存的伪密码
do
{
printf("请输入密码>>");
int i = 0;
int j = 0;
while (i < 20)
{
rr[i] = getch(); // getch()从控制台输入一各字符但是不显示
if (rr[i] == '\b' && i > 0) //遇到空格不管
{
continue;
}
if (rr[i] == '\b' && i == 0) //如果在最开始就按退格键,就让i=-1
{
i = 0;
continue;
}
if (rr[i] == '\r') //如果输入的是回车,就退出输入循环
{
break;
}
i++;
putchar('*');
}
rr[i] = '\0';
strcpy(weimima, a.pwd);
for (int i = 0; i < strlen(rr); ++i)
{
mima[i] = weimima[i] - i;
}
mima[strlen(rr)] = '\0';
if (!strcmp(mima, rr)) //输入的密码与文件中的相同
{
printf("\n\t登录成功!欢迎使用!\n");
fclose(pf);
pf = NULL; //置空,避免野指针
common_usermenu(head);
return;
}
else
{
printf("\n\t密码输入错误,请重新输入\n");
}
} while (strcmp(mima, rr));
}
main.c文件
#include "flight.h"
int main(int argc, char *argv[])
{
node *head = create_Init();//头节点
int flag = 1, choose1;
while (flag)
{
main_UI();
char choose[20];
scanf("%s", choose);
choose1 = atoi(choose);//转成整型容错,防止系统崩溃
switch (choose1)
{
case 1:
regis();//注册
break;
case 2:
login(head);//登录
break;
case 3:
flag = 0;//退出
break;
case 1443003064: //管理员入口:不显示此功能,管理员自知,在显示功能外(隐藏入口)
admmenu(head);
break;
default:
printf("\n请输入正确的序号!\n");
break;
}
}
return 0;
}
makefile文件
FLIGHT : main.o flight.o
gcc -g main.o flight.o -o FLIGHT
main.o : main.c
gcc -g -c main.c -o main.o
flight.o: flight.c
gcc -g -c flight.c -o flight.o
clean:
rm *.txt main.o flight.o