简单的C语言航班管理系统

主要文件有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

        还有很多不足,还有很多功能可以实现,如购票,退票等等一些功能,莫嫌弃。

  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值