主要文件有mian.c 、interface.h、interface.c 、user.h、 user.c、userFile、flightMS.h、flightMS.c、flightFile.txt、Makefile
主要功能:实现了一个超级用户和普通用户,超级用户可以增删改查航班,普通用户只可以查询航班,使用makefile进行编译。
main.c 主要是不想在main函数写太多东西,所以直接只调用一个主页面函数,功能都在对应的页面中实现
#include "interface.h"
int main(int argc, char *argv[]){
welcomeUI();
return 0;
}
interface.h 各个页面的头,这样可以让代码有层次感
#include "flightMS.h"
#include "user.h"
//界面头
//欢迎页面
void welcomeUI();
//用户界面
void userUI();
//登录页面
void loginUI(list_t* head, dclist_t* dchead);
//用户注册页面
void enrollUI(list_t* head, dclist_t* dchead);
//超级用户航班页面
void rootFlightUI(list_t* head, dclist_t* dchead);
//普通用户航班页面
void commonFlightUI(list_t* head, dclist_t* dchead);
//添加航班页面
void insertFlightUI(list_t* head, dclist_t* dchead);
//修改航班页面
void updataFlightUI(list_t* head, dclist_t* dchead);
interface.c 实现头文件中的函数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "interface.h"
//欢迎页面
void welcomeUI(){
system("clear");
printf("\t\t--------------------------------------------------\n");
printf("\t\t \n");
printf("\t\t \n");
printf("\t\t 欢迎使用本航班系统 \n");
printf("\t\t \n");
printf("\t\t \n");
printf("\t\t \n");
printf("\t\t \n");
printf("\t\t \n");
printf("\t\t--------------------按回车键继续--------------------\n");
printf("\t\t");
getchar();
system("clear");
userUI();
}
//用户界面
void userUI(){
//用字符输入的原因是防止输入其他字符而导致程序奔溃
char c;
list_t * head = create_list();
dclist_t* dchead = create_dclist();
read_user_file(head);
delete_tlist(head);
read_flight_file(dchead);
delete_tdclist(dchead);
if(head == NULL){
perror("create_list failed\n");
exit(1);
}
printf("\t\t--------------------------------------------------\n");
printf("\t\t 用户登录页面 \n");
printf("\t\t \n");
printf("\t\t 1.登陆用户 \n");
printf("\t\t 2.注册用户 \n");
printf("\t\t \n");
printf("\t\t \n");
printf("\t\t-------------------请输入对应数字-------------------\n");
printf("\t\t");
scanf("%c", &c);
//清空缓存区,把换行符(\n)拿走
getchar();
if(c == '1'){
//清空当前终端页面//欢迎页面
void welcomeUI();
system("clear");
loginUI(head, dchead);
}else if(c == '2'){
system("clear");
enrollUI(head, dchead);
}else{
system("clear");
loginUI(head, dchead);
}
}
//登录页面
void loginUI(list_t* head, dclist_t* dchead){
char c;
user_t user;
printf("\t\t--------------------------------------------------\n");
printf("\t\t 请你登录 \n");
printf("\t\t \n");
printf("\t\t 用户名: \n");
printf("\t\t");
fgets(user.name,sizeof(user.name), stdin);
user.name[strlen(user.name)-1] = '\0';
printf("\t\t 密 码: \n");
printf("\t\t");
fgets(user.password,sizeof(user.password), stdin);
user.password[strlen(user.password)-1] = '\0';
printf("\t\t \n");
printf("\t\t \n");
printf("\t\t-------------------请按回车登录----------------------\n");
user_t* resUser = NULL;
resUser = find_user(head, &user, cmpUserAll);
printf("\t\t");
getchar();
if(resUser != NULL){
printf("\t\t登录成功\n");
//登录成功
if(resUser->flag == 0){
system("clear");
//超级用户页面
rootFlightUI(head, dchead);
}else{
system("clear");
//超级用户页面
commonFlightUI(head, dchead);
}
}else{
//登录失败,账号或者密码不正确
printf("\t\t登录失败,账号或者密码不正确,输入1跳转注册页面,输入其他不跳转页面\n");
printf("\t\t");
scanf("%c",&c);
//清空缓存区,把换行符(\n)拿走
getchar();
if(c == '1'){
system("clear");
//注册页面
enrollUI(head, dchead);
}else{
system("clear");
//登录页面
loginUI(head, dchead);
}
}
}
//用户注册页面
void enrollUI(list_t* head, dclist_t* dchead){
int flag;
user_t user;
//区分超级用户和普通用户
if(head->next == NULL){
flag = 0;
}else{
flag = 1;
}
printf("\t\t--------------------------------------------------\n");
printf("\t\t 请你注册 \n");
printf("\t\t \n");
printf("\t\t 用户名: \n");
printf("\t\t");
fgets(user.name,sizeof(user.name), stdin);
user.name[strlen(user.name)-1] = '\0';
printf("\t\t 密 码: \n");
printf("\t\t");
fgets(user.password,sizeof(user.password), stdin);
user.password[strlen(user.password)-1] = '\0';
printf("\t\t \n");
printf("\t\t \n");
printf("\t\t------------------按回车注册------------------------\n");
user.flag = flag;
int res = insert_user(head, &user);
if(res == -1){
printf("\t\t注册失败,请重新填写用户名\n");
enrollUI(head, dchead);
}else{
//注册成功写入文件中
save_oneUser_file(head);
printf("\t\t注册成功,请按回车回车,进入登录页面进行登录\n");
printf("\t\t");
getchar();
system("clear");
loginUI(head, dchead);
}
}
//超级用户航班页面
void rootFlightUI(list_t* head, dclist_t* dchead){
char c;
printf("\t\t-----------------欢迎使用本航班系统------------------\n");
printf("\t\t \n");
printf("\t\t 1.显示全部航班 \n");
printf("\t\t 2.按照类型查询航班 \n");
printf("\t\t 3.按照起飞日期和票价排列显示航班 \n");
printf("\t\t 4.根据起始地和目的地查询航班 \n");
printf("\t\t 5.根据出发日期查询航班 \n");
printf("\t\t 6.添加航班 \n");
printf("\t\t 7.删除航班 \n");
printf("\t\t 8.修改航班 \n");
printf("\t\t 9.切换用户 \n");
printf("\t\t 0.退出系统 \n");
printf("\t\t \n");
printf("\t\t------------------请输入对应的数字-------------------\n");
printf("\t\t");
scanf("%c",&c);
//清空缓存区
getchar();
if(c == '1'){
system("clear");
print_flight(dchead,showAll);
printf("\t\t已帮你查询完毕,按回车回到主页面\n");
printf("\t\t");
getchar();
system("clear");
rootFlightUI(head, dchead);
}else if(c == '2'){
system("clear");
flight_t flight;
char fltype[16];
printf("\t\t请输入你要查询的航班类型:\n");
printf("\t\t");
fgets(flight.fltype, sizeof(flight.fltype), stdin);
flight.fltype[strlen(flight.fltype) - 1] = '\0';
find_flight_type(dchead, &flight, compareType, showAll);
printf("\t\t已帮你查询完毕,按回车回到主页面\n");
printf("\t\t");
getchar();
system("clear");
rootFlightUI(head, dchead);
}else if(c == '3'){
system("clear");
sort_flight_date_fare(dchead);
printf("\t\t已帮你查询完毕,按回车回到主页面\n");
printf("\t\t");
getchar();
system("clear");
rootFlightUI(head, dchead);
}else if(c == '4'){
system("clear");
flight_t flight;
printf("\t\t请输入始发地:\n");
printf("\t\t");
fgets(flight.begaddr, sizeof(flight.begaddr), stdin);
flight.begaddr[strlen(flight.begaddr) - 1] = '\0';
printf("\t\t请输入终点站:\n");
printf("\t\t");
fgets(flight.endaddr, sizeof(flight.endaddr), stdin);
flight.endaddr[strlen(flight.endaddr) - 1] = '\0';
find_flight_begaddr_endaddr(dchead, &flight);
printf("\t\t已帮你查询完毕,按回车回到主页面\n");
printf("\t\t");
getchar();
system("clear");
rootFlightUI(head, dchead);
}else if(c == '5'){
system("clear");
flight_t flight;
printf("\t\t请输入你要出发的日期(格式为yyyy-MM-dd,例如2023-01-09):\n");
printf("\t\t");
fgets(flight.fldate, sizeof(flight.fldate), stdin);
flight.fldate[strlen(flight.fldate) - 1] = '\0';
find_flight_fldate(dchead, &flight);
printf("\t\t已帮你查询完毕,按回车回到主页面\n");
printf("\t\t");
getchar();
system("clear");
rootFlightUI(head, dchead);
}else if(c == '6'){
system("clear");
insertFlightUI(head, dchead);
}else if(c == '7'){
flight_t flight ={0};
int i = 0;
system("clear");
printf("\t\t请输入你要删除的航班号id:\n");
printf("\t\t");
fgets(flight.id, sizeof(flight.id), stdin);
flight.id[strlen(flight.id) - 1] = '\0';
i = delete_dclist(dchead, &flight, compareId);
if(i == 0){
save_flight_file(dchead);
printf("\t\t删除成功,请按回车继续\n");
printf("\t\t");
getchar();
system("clear");
rootFlightUI(head, dchead);
}else{
printf("\t\t系统忙,请稍后...\n");
printf("\t\t按回车回到主页面\n");
printf("\t\t");
getchar();
system("clear");
rootFlightUI(head, dchead);
}
}else if(c == '8'){
system("clear");
updataFlightUI(head, dchead);
}else if(c == '9'){
system("clear");
loginUI(head, dchead);
}else if(c == '0'){
save_user_file(head);
exit(0);
}else{
system("clear");
rootFlightUI(head, dchead);
}
}
//普通用户航班页面
void commonFlightUI(list_t* head, dclist_t* dchead){
char c;
printf("\t\t-----------------欢迎使用本航班系统------------------\n");
printf("\t\t \n");
printf("\t\t \n");
printf("\t\t 1.显示全部航班 \n");
printf("\t\t 2.按照类型查询航班 \n");
printf("\t\t 3.按照起飞日期和票价排列显示航班 \n");
printf("\t\t 4.根据起始地和目的地查询航班 \n");
printf("\t\t 5.根据出发日期查询航班 \n");
printf("\t\t 6.切换用户 \n");
printf("\t\t 7.退出系统 \n");
printf("\t\t \n");
printf("\t\t \n");
printf("\t\t------------------请输入对应的数字-------------------\n");
printf("\t\t");
scanf("%c",&c);
//清空缓存区
getchar();
if(c == '1'){
system("clear");
print_flight(dchead,showAll);
printf("\t\t已帮你查询完毕,按回车回到主页面\n");
printf("\t\t");
getchar();
system("clear");
commonFlightUI(head, dchead);
}else if(c == '2'){
system("clear");
flight_t flight;
printf("\t\t请输入你要查询的航班类型:\n");
printf("\t\t");
fgets(flight.fltype, sizeof(flight.fltype), stdin);
flight.fltype[strlen(flight.fltype) - 1] = '\0';
find_flight_type(dchead, &flight, compareType, showAll);
printf("\t\t已帮你查询完毕,按回车回到主页面\n");
printf("\t\t");
getchar();
system("clear");
commonFlightUI(head, dchead);
}else if(c == '3'){
system("clear");
sort_flight_date_fare(dchead);
printf("\t\t已帮你查询完毕,按回车回到主页面\n");
printf("\t\t");
getchar();
system("clear");
commonFlightUI(head, dchead);
}else if(c == '4'){
system("clear");
flight_t flight;
printf("\t\t请输入始发地:\n");
printf("\t\t");
fgets(flight.begaddr, sizeof(flight.begaddr), stdin);
flight.begaddr[strlen(flight.begaddr) - 1] = '\0';
printf("\t\t请输入终点站:\n");
printf("\t\t");
fgets(flight.endaddr, sizeof(flight.endaddr), stdin);
flight.endaddr[strlen(flight.endaddr) - 1] = '\0';
find_flight_begaddr_endaddr(dchead, &flight);
printf("\t\t已帮你查询完毕,按回车回到主页面\n");
printf("\t\t");
getchar();
system("clear");
commonFlightUI(head, dchead);
}else if(c == '5'){
system("clear");
flight_t flight;
printf("\t\t请输入你要出发的日期(格式为yyyy-MM-dd,例如2023-01-09):\n");
printf("\t\t");
fgets(flight.fldate, sizeof(flight.fldate), stdin);
flight.fldate[strlen(flight.fldate) - 1] = '\0';
find_flight_fldate(dchead, &flight);
printf("\t\t已帮你查询完毕,按回车回到主页面\n");
printf("\t\t");
getchar();
system("clear");
commonFlightUI(head, dchead);
}else if(c == '6'){
system("clear");
loginUI(head, dchead);
}else if(c == '7'){
save_user_file(head);
exit(0);
}else{
system("clear");
commonFlightUI(head, dchead);
}
}
//添加航班页面
void insertFlightUI(list_t* head, dclist_t* dchead){
char ch[8];
flight_t flight;
printf("\t\t请输入航班号:\n");
printf("\t\t");
fgets(flight.id, sizeof(flight.id), stdin);
flight.id[strlen(flight.id) - 1] = '\0';
printf("\t\t请输入起始站:\n");
printf("\t\t");
fgets(flight.begaddr, sizeof(flight.begaddr), stdin);
flight.begaddr[strlen(flight.begaddr) - 1] = '\0';
printf("\t\t请输入终点站:\n");
printf("\t\t");
fgets(flight.endaddr, sizeof(flight.endaddr), stdin);
flight.endaddr[strlen(flight.endaddr) - 1] = '\0';
printf("\t\t请输入飞机起飞日期(格式为yyyy-MM-dd,例如2023-01-09):\n");
printf("\t\t");
fgets(flight.fldate, sizeof(flight.fldate), stdin);
flight.fldate[strlen(flight.fldate) - 1] = '\0';
printf("\t\t请输入飞机类型:\n");
printf("\t\t");
fgets(flight.fltype, sizeof(flight.fltype), stdin);
flight.fltype[strlen(flight.fltype) - 1] = '\0';
printf("\t\t请输入飞机起飞时间(格式为HH:mm,例如09:01 20:10):\n");
printf("\t\t");
fgets(flight.begtime, sizeof(flight.begtime), stdin);
flight.begtime[strlen(flight.begtime) - 1] = '\0';
printf("\t\t请输入飞机降落时间(格式为HH:mm,例如09:01 20:10):\n");
printf("\t\t");
fgets(flight.endtime, sizeof(flight.endtime), stdin);
flight.endtime[strlen(flight.endtime) - 1] = '\0';
printf("\t\t请输入飞机的票价:\n");
printf("\t\t");
scanf("%s",ch);
getchar();
float fare = atoi(ch);
flight.fare = fare;
int res = -2;
char c;
res = insert_flight(dchead, &flight);
if(res == 0){
write_flight_file(dchead);
system("clear");
printf("\t\t添加成功,请按回车返回用户主页面\n");
printf("\t\t");
getchar();
system("clear");
rootFlightUI(head, dchead);
}else{
system("clear");
printf("\t\t添加失败,系统忙,请稍后...\n");
printf("\t\t输入1返回主页面,输入其他则重新添加\n");
printf("\t\t");
scanf("%c", &c);
getchar();
if(c == '1'){
system("clear");
rootFlightUI(head, dchead);
}else{
system("clear");
insertFlightUI(head, dchead);
}
}
}
//修改航班页面
void updataFlightUI(list_t* head, dclist_t* dchead){
flight_t flight;
char c;
printf("\t\t请输入要修改的航班号:\n");
printf("\t\t");
fgets(flight.id, sizeof(flight.id), stdin);
flight.id[strlen(flight.id) - 1] = '\0';
printf("\t\t请输入航班起飞时间(格式为HH:mm,例如09:01 20:10):\n");
printf("\t\t");
fgets(flight.begtime, sizeof(flight.begtime), stdin);
flight.begtime[strlen(flight.begtime) - 1] = '\0';
printf("\t\t请输入航班降落时间(格式为HH:mm,例如09:01 20:10):\n");
printf("\t\t");
fgets(flight.endtime, sizeof(flight.endtime), stdin);
flight.endtime[strlen(flight.endtime) - 1] = '\0';
if(!updata_dclist(dchead, &flight, compareId)){
save_flight_file(dchead);
printf("\t\t修改成功,请按回车回到主页面");
getchar();
system("clear");
rootFlightUI(head, dchead);
}else{
printf("\t\t系统忙,请稍后...\n");
printf("\t\t输入1回到主页面,其他回车不跳转\n");
printf("\t\t");
scanf("%c", &c);
getchar();
if(c == '1'){
system("clear");
rootFlightUI(head, dchead);
}else{
system("clear");
updataFlightUI(head,dchead);
}
}
}
flightMS.h 航班存储的头,主要定义航班结构体和方法名,这里定义的是双向循环链表来存
#ifndef NODE
#define NODE
//航班信息结构体
typedef struct flight{
char id[16]; //航班号
char begaddr[16]; //起点站
char endaddr[16]; //终点站
char fldate[16]; //班期
char fltype[16]; //航班类型(属于哪家公司)
char begtime[8]; //起飞时间
char endtime[8]; //到达时间
float fare; //票价
}flight_t;
//双向循环链表结构
typedef struct dclinklist{
struct dclinklist* before; //前面一个节点
flight_t* flight; //存储航班
struct dclinklist* next; //下一个节点
}dclist_t;
#endif
//创建双向循环链表的头
dclist_t* create_dclist();
//添加航班
int insert_flight(dclist_t* dchead, flight_t* flight);
//节点数,不包括头
int length_dclist(dclist_t* dchead);
typedef void (*showfun_t)(flight_t* flight);
//航线
void showRoute(flight_t* flight);
void showTime(flight_t* flight);
void showFare(flight_t* flight);
void showData(flight_t* flight);
void showType(flight_t* flight);
void showAll(flight_t* flight);
//打印函数
void print_flight(dclist_t* head, showfun_t showFun);
//比较函数指针(第一个是链表中本身的数据,第二个是页面传过来的数据)
typedef int (*comparefun_t)(flight_t * dclistFlight, flight_t* flight);
int compareId(flight_t * dclistFlight, flight_t* flight);
int compareType(flight_t* dclistFlight, flight_t* flight);
int compareFldate(flight_t* dclistFlight, flight_t* flight);
//根据航班号删除航班
int delete_dclist(dclist_t* dchead, flight_t * id, comparefun_t comparefun);
//删除尾节点
int delete_tdclist(dclist_t * dchead);
//根据航班号修改航班中时间信息
int updata_dclist(dclist_t* dchead, flight_t * flight, comparefun_t comparefun);
//按照类型查询航班
int find_flight_type(dclist_t* dchead, flight_t* flight, comparefun_t comparefun, showfun_t showfun);
//根日期票价排序查看航班
int sort_flight_date_fare(dclist_t* dchead);
//根据起始地和目的地查询航班
int find_flight_begaddr_endaddr(dclist_t* dchead, flight_t* flight);
//根据日期查询航班
int find_flight_fldate(dclist_t* dchead, flight_t* flight);
//从链表中的数据保存到文件中
void save_flight_file(dclist_t* dchead);
//添加一条航班就往文件中保存
void write_flight_file(dclist_t* dchead);
//从文件中读取航班
void read_flight_file(dclist_t* dchead);
flightMS.c 实现对应头文件中的方法
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "flightMS.h"
//创建双向循环链表的头
dclist_t* create_dclist(){
dclist_t* dchead = (dclist_t*)malloc(sizeof(dclist_t));
if(dchead == NULL){
perror("malloc failed\n");
return NULL;
}
dchead->flight = NULL;
dchead->before = dchead;
dchead->next = dchead;
return dchead;
}
//添加航班(尾插)
int insert_flight(dclist_t* dchead, flight_t* flight){
if(dchead == NULL || flight == NULL){
perror("error\n");
return -1;
}
//申请节点空间
dclist_t* newnode = (dclist_t*)malloc(sizeof(dclist_t));
if(newnode == NULL){
perror("malloc failed\n");
return -1;
}
//申请数据空间
newnode->flight = (flight_t*)malloc(sizeof(flight_t));
if(newnode->flight == NULL){
perror("malloc failed\n");
return -1;
}
//赋值
//*newnode->flight = *flight;
memcpy(newnode->flight, flight, sizeof(flight_t));
newnode->before = dchead->before;
newnode->next = dchead;
dchead->before->next = newnode;
dchead->before = newnode;
return 0;
}
//节点数,不包括头
int length_dclist(dclist_t* dchead){
if(dchead == NULL || dchead->next == dchead){
perror("error\n");
return -1;
}
dclist_t * temp = dchead->next;
int i = 1;
while (temp->next != dchead){
++i;
temp = temp->next;
}
return i;
}
//打印定义的函数指针
typedef void (*showfun_t)(flight_t* flight);
void showId(flight_t* flight){
printf("航班号%s\n",flight->id);
}
void showRoute(flight_t* flight){
printf("航线:%s-----%s\n",flight->begaddr,flight->endaddr);
}
void showTime(flight_t* flight){
printf("时间段:%s-----%s\n",flight->begtime,flight->endtime);
}
void showFare(flight_t* flight){
printf("票价:%.2f\n",flight->fare);
}
void showData(flight_t* flight){
printf("航班日期:%s\n",flight->fldate);
}
void showType(flight_t* flight){
printf("航班类型:%s\n",flight->fltype);
}
void showAll(flight_t* flight){
printf("%s %s---->%s %s %s %s %s %.2f\n",
flight->id, flight->begaddr, flight->endaddr,
flight->fldate, flight->fltype, flight->begtime,
flight->endtime,flight->fare);
puts("");
}
//打印函数
void print_flight(dclist_t* dchead, showfun_t showFun){
if(dchead == NULL || dchead->next == dchead){
perror("error\n");
return;
}
dclist_t *temp = dchead->next;
printf("航班号 起始站 终点站 航班日期 航班类型 起飞时间 降落时间 票价\n");
while(temp != dchead){
showFun(temp->flight);
temp = temp->next;
}
}
//比较函数指针(第一个是链表中本身的数据,第二个是页面传过来的数据)
typedef int (*comparefun_t)(flight_t * dclistFlight, flight_t* flight);
int compareId(flight_t * dclistFlight, flight_t* flight){
return strcmp(dclistFlight->id, flight->id);
}
int compareType(flight_t* dclistFlight, flight_t* flight){
return strcmp(dclistFlight->fltype, flight->fltype);
}
int compareFldate(flight_t* dclistFlight, flight_t* flight){
return strcmp(dclistFlight->fldate, flight->fldate);
}
//比较起始地和目的地
int compareAddress(flight_t* dclistFlight, flight_t* flight){
int beg = strcmp(dclistFlight->begaddr, flight->begaddr);
int end = strcmp(dclistFlight->endaddr, flight->endaddr);
if(beg == 0 && end == 0){
return 0;
}
return -1;
}
//根据航班号删除航班
int delete_dclist(dclist_t* dchead, flight_t* flight, comparefun_t comparefun){
if(dchead == NULL || dchead->next == dchead || flight == NULL){
perror("error\n");
return -1;
}
dclist_t* temp = dchead->next;
int res;
while(temp != dchead){
res = comparefun(temp->flight, flight);
if(res == 0){
temp->before->next = temp->next;
temp->next->before = temp->before;
free(temp->flight);
free(temp);
return 0;
}
temp = temp->next;
}
return -1;
}
//删除链表中的尾节点,读文件最后一行重复读
int delete_tdclist(dclist_t * dchead){
if(dchead == NULL){
perror("error\n");
return -1;
}
dclist_t* temp = dchead->before;
temp->before->next = temp->next;
temp->next->before = temp->before;
free(temp->flight);
free(temp);
return 0;
}
//根据航班号修改航班中时间信息
int updata_dclist(dclist_t* dchead, flight_t * flight, comparefun_t comparefun){
if(dchead == NULL || dchead->next == dchead || flight == NULL){
perror("error\n");
return -1;
}
//先查找出对应的航班
dclist_t* temp = dchead->next;
while(temp != dchead){
if(!comparefun(temp->flight,flight)){
break;
}
temp = temp->next;
}
if(temp == dchead){
perror("无此航班号\n");
return -1;
}
//修改原航班的起飞时间,和降落时间
strcpy(temp->flight->begtime, flight->begtime);
strcpy(temp->flight->endtime, flight->endtime);
return 0;
}
//按照类型查询航班
int find_flight_type(dclist_t* dchead, flight_t* flight, comparefun_t comparefun, showfun_t showfun){
if(dchead == NULL || dchead->next == dchead || flight == NULL){
perror("error\n");
return -1;
}
dclist_t* temp = dchead->next;
while(temp != dchead){
if(!comparefun(temp->flight, flight)){
showfun(temp->flight);
}
temp = temp->next;
}
return 0;
}
//根日期票价排序查看航班
int sort_flight_date_fare(dclist_t* dchead){
if(dchead == NULL || dchead->next == dchead){
perror("error\n");
return -1;
}
int len = length_dclist(dchead);
flight_t * arr[len];
dclist_t* temp = dchead->next;
int i = 0;
//讲链表中的数据全部放入指针数组中
while(temp != dchead){
arr[i] = temp->flight;
temp = temp->next;
++i;
}
//将数组中的航班进行排序
flight_t* temp2 = NULL;
for(int j = 0; j < len-1; j++){
for(int k = 0; k < len-1-j; k++){
if(compareFldate(arr[k], arr[k+1]) > 0){
temp2 = arr[k];
arr[k] = arr[k+1];
arr[k+1] = temp2;
}
if(!compareFldate(arr[k], arr[k+1])){
if(arr[k]->fare > arr[k+1]->fare){
temp2 = arr[k];
arr[k] = arr[k+1];
arr[k+1] = temp2;
}
}
}
}
temp = NULL;
//遍历输出数组中的元素
for(int z = 0; z < len; z++){
/*printf("航班号:%s\t起始站:%s\t终点站:%s\t航班日期:%s\t航班类型:%s\t起飞时间:%s\t降落时间:%s\t票价:%.2f\n",
arr[z]->id, arr[z]->begaddr, arr[z]->endaddr,
arr[z]->fldate, arr[z]->fltype, arr[z]->begtime,
arr[z]->endtime, arr[z]->fare);
puts("");*/
showAll(arr[z]);
}
return 0;
}
//根据起始地和目的地查询航班
int find_flight_begaddr_endaddr(dclist_t* dchead, flight_t* flight){
if(dchead == NULL || flight == NULL || dchead->next == dchead){
return -1;
}
dclist_t* temp = dchead->next;
while(temp != dchead){
if(!compareAddress(temp->flight, flight)){
showAll(temp->flight);
}
temp = temp->next;
}
return 0;
}
//根据日期查询航班
int find_flight_fldate(dclist_t* dchead, flight_t* flight){
if(dchead == NULL || flight == NULL || dchead->next == dchead){
return -1;
}
dclist_t* temp = dchead->next;
while(temp != dchead){
if(!compareFldate(temp->flight, flight)){
showAll(temp->flight);
}
temp = temp->next;
}
return 0;
}
#if 1
//从链表中的数据保存到文件中
void save_flight_file(dclist_t* dchead){
if(dchead == NULL){
perror("error\n");
return;
}
FILE * fp;
fp = fopen("flightFile.txt", "w+");
fprintf(fp, "航班号 起始站 终点站 航班日期 航班类型 起飞时间 降落时间 票价\n");
dclist_t* temp = dchead->next;
while(temp != dchead){
fprintf(fp, "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%.2f\n", temp->flight->id, temp->flight->begaddr, temp->flight->endaddr,
temp->flight->fldate, temp->flight->fltype, temp->flight->begtime,
temp->flight->endtime, temp->flight->fare);
temp = temp->next;
}
fclose(fp);
}
#endif
//添加一条航班就往文件中保存
void write_flight_file(dclist_t* dchead){
if(dchead == NULL){
perror("error\n");
return;
}
//文件指针
FILE* fp;
fp = fopen("flightFile.txt","a");
if(fp == NULL){
perror("打开文件失败\n");
return;
}
dclist_t* temp = dchead->before;
fprintf(fp,"%s %s %s %s %s %s %s %.2f\n", temp->flight->id,temp->flight->begaddr, temp->flight->endaddr, temp->flight->fldate, temp->flight->fltype, temp->flight->begtime, temp->flight->endtime, temp->flight->fare);
fclose(fp);
}
//从文件中读取航班
void read_flight_file(dclist_t* dchead){
if(dchead == NULL){
perror("error\n");
return;
}
//文件指针
FILE* fp;
char buf[1024];
char id[16], begaddr[16], endaddr[16], fldate[16], fltype[16], begtime[8], endtime[8];
fp = fopen("flightFile.txt","r");
if(fp == NULL){
perror("打开文件失败\n");
return;
}
//不读第一行
fgets(buf, sizeof(buf),fp);
flight_t flight;
while(!feof(fp)){
fscanf(fp, "%s %s %s %s %s %s %s %f", id, begaddr, endaddr, fldate, fltype, begtime, endtime, &flight.fare);
strcpy(flight.id,id);
strcpy(flight.begaddr,begaddr);
strcpy(flight.endaddr,endaddr);
strcpy(flight.fldate,fldate);
strcpy(flight.fltype,fltype);
strcpy(flight.begtime,begtime);
strcpy(flight.endtime,endtime);
insert_flight(dchead, &flight);
}
fclose(fp);
}
user.h 用户头,用来保存用户信息,单链表数据结构
#ifndef USER
#define USER
//用户的结构体
typedef struct user{
char name[16]; //用户名
char password[16]; //密码
int flag; //标记 存0和1 0表示超级用户 1表示普通用户
}user_t;
//存储用户的链表
typedef struct linklist{
user_t* user; //存储用户
struct linklist* next; //下一个节点
}list_t;
#endif
//创建链表头
list_t* create_list();
//注册用户,往链表中存用户数据
int insert_user(list_t* head, user_t* user);
//比较用户的信息
//第一个为链表中的信息,第二个为页面过来的信息
typedef int (*cmpfun_t)(user_t* listUser, user_t* user);
int cmpUserName(user_t* listUser, user_t* user);
int cmpUserPassword(user_t* listUser, user_t* user);
int cmpUserAll(user_t* listUser, user_t* user);
//查询用户
user_t* find_user(list_t* head, user_t* user, cmpfun_t cmpfun);
//用户个数(链表长度)
int length_list(list_t* head);
//删除链表尾
int delete_tlist(list_t* head);
//往文件中存储用户信息
void save_user_file(list_t* head);
//每次注册成功把该条写到文件中
void save_oneUser_file(list_t* head);
//读取文件中的数据到链表中
void read_user_file(list_t* head);
user.c 实现对应头文件中的方法
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "user.h"
//创建链表头
list_t* create_list(){
list_t *head = (list_t*)malloc(sizeof(list_t));
if(NULL == head){
perror("malloc failed\n");
return NULL;
}
head->user = NULL;
head->next = NULL;
return head;
}
//注册用户(尾插)
int insert_user(list_t* head, user_t* user){
if(head == NULL || user == NULL){
perror("head is NULL or user is NULL\n");
return -1;
}
//找尾
list_t* temp = head;
while(temp->next != NULL){
temp = temp->next;
}
list_t* newnode = (list_t*)malloc(sizeof(list_t));
if(newnode == NULL){
perror("malloc failed\n");
return -1;
}
newnode->user = (user_t*)malloc(sizeof(user_t));
if(newnode->user == NULL){
perror("malloc failed\n");
return -1;
}
*newnode->user = *user;
newnode->next = temp->next;
temp->next = newnode;
return 0;
}
//比较用户的信息
//第一个为链表中的信息,第二个为页面过来的信息
typedef int (*cmpfun_t)(user_t* listUser, user_t* user);
int cmpUserName(user_t* listUser, user_t* user){
return strcmp(listUser->name,user->name);
}
int cmpUserPassword(user_t* listUser, user_t* user){
return strcmp(listUser->password,user->password);
}
int cmpUserAll(user_t* listUser, user_t* user){
int a, b;
//printf("----------------------------------------------\n");
//printf("%s\t%s\n",user->name,user->password);
//printf("%s\t%s\n",listUser->name,listUser->password);
a = strcmp(listUser->name,user->name);
//printf("a = %d\n",a);
b = strcmp(listUser->password,user->password);
//printf("b = %d\n",b);
if(a == 0 && b == 0){
return 0;
}
return -1;
}
//查询用户
user_t* find_user(list_t* head, user_t* user, cmpfun_t cmpfun){
if(head == NULL || user == NULL || head->next == NULL){
return NULL;
}
//printf("%s\t%s\n",user->name,user->password);
list_t* temp = head->next;
while(temp != NULL){
if(cmpfun(temp->user, user) == 0){
//printf("name:%s\tpassword:%s\tflag:%d\n",temp->user->name,temp->user->password,temp->user->flag);
return temp->user;
}
temp = temp->next;
}
return NULL;
}
//查询链表长度(不包括头)
int length_list(list_t* head){
if(head == NULL || head->next == NULL){
return 0;
}
list_t* temp = head->next;
int i = 1;
while(temp->next != NULL){
++i;
temp = temp->next;
}
return i;
}
//删除最后一个节点,因为文件读取的会把'\n'当成最后一行
//即链表会多出一个数据,重复有效数据的最后一行
int delete_tlist(list_t* head){
if(head == NULL){
perror("error\n");
return -1;
}
list_t* temp = head->next;
list_t* before = head;
while(temp->next != NULL){
before = temp;
temp = temp->next;
}
before->next = temp->next;
free(temp->user);
free(temp);
return 0;
}
//将链表中的数据存储到文件中
void save_user_file(list_t* head){
if(head == NULL || head->next == NULL){
return;
}
FILE* fp;
list_t* temp = head->next;
fp = fopen("userFile.txt","w+");//w+ 清空重写,r+ 不会清空,只会从头开始写,保留原文件中没有被覆盖的内容
if(fp == NULL){
perror("打开文件失败\n");
return;
}
fprintf(fp,"账号\t密码\t标记\n");
while(temp != NULL){
fprintf(fp,"%s\t%s\t%d\n", temp->user->name, temp->user->password, temp->user->flag);
temp = temp->next;
}
fclose(fp);
}
//每次注册成功把该条写到文件中
void save_oneUser_file(list_t* head){
if(head == NULL){
return;
}
FILE* fp;
list_t* temp = head->next;
//把指针一到链表尾部
while(temp->next != NULL){
temp = temp->next;
}
fp = fopen("userFile.txt","a");
if(fp == NULL){
perror("打开文件失败\n");
return;
}
fprintf(fp,"%s\t%s\t%d\n", temp->user->name, temp->user->password, temp->user->flag);
fclose(fp);
}
//读取文件中的数据到链表中
void read_user_file(list_t* head){
if(head == NULL){
return;
}
FILE *fp;
char buf[1024], name[16], password[16];
fp = fopen("userFile.txt", "r");
if(fp == NULL){
perror("打开文件失败\n");
return;
}
//不读出第一行
fgets(buf, sizeof(buf), fp);
user_t user;
while(!feof(fp)){
fscanf(fp, "%s%s%d", name, password, &user.flag);
strcpy(user.name, name);
strcpy(user.password,password);
insert_user(head, &user);
}
fclose(fp);
}
userFile.txt 这里的文件内容可以为空,第一个注册的用户默认为超级用户,之后注册的均为普通用户,这个文件只是把链表中数据存到了文件中,为了防止程序关闭重启就啥都没有了
账号 密码 标记
root 123 0
zhangsan 123 1
flightMS.txt 默认有一些航班,方便操作,也可以为空,自己一个个加 ,数据乱编
航班号 起始站 终点站 航班日期 航班类型 起飞时间 降落时间 票价
Y-3001 北京 上海 2023-03-10 南方航空 10:23 12:30 576.00
Z-2011 武汉 青岛 2023-03-10 东方航空 12:23 13:00 505.00
Y-4034 厦门 长春 2023-02-23 上海航空 09:23 11:30 606.00
S-1001 长沙 北京 2023-03-30 北京航空 23:23 01:30 400.00
X-2301 云南 山东 2023-04-11 山东航空 15:23 18:30 880.00
b-2020 长沙 上海 2023-04-20 南方航空 01:20 11:30 666.00
S-1010 长沙 北京 2023-03-01 北京航空 08:30 10:00 450.00
Z-2023 北京 上海 2023-10-15 北京航空 10:30 12:00 555.50
a-1001 上海 长沙 2023-11-23 厦门航空 12:30 02:00 520.00
b-2001 北京 广州 2023-05-20 北京航空 13:14 15:20 1314.00
Makefile 方便编译,直接make就行了,不需要gcc
test:main.o interface.o user.o flightMS.o
gcc -o test main.o interface.o user.o flightMS.o
main.o:
gcc -c main.c
interface.o:
gcc -c interface.c interface.h
user.o:
gcc -c user.c user.h
flightMS.o:
gcc -c flightMS.c flightMS.h
clean:
rm test *.o *.h.gch
还有很多不足,还有很多功能可以实现,如购票,退票等等一些功能,莫嫌弃。