测试环境Ubuntu_1604_64bit
Makefile多文件联合编译工具,这个是写的很简单的一个Makefile了,编译直接make就行了,然后make clean 是清除目标文件重新编译的。
Makefile
hangban:
gcc -o hangban main.c customer.h flight.h customer.c flight.c
clean:
rm hangban
main 函数写的比较乱,最好的就是不要在main函数里写功能,把功能在写的函数里,main函数只调用函数,这样代码简洁明了,代码的可读性会高很多,由于这也是之前写的项目,基础不太好,也是在后来慢慢的学习过程中才改变习惯。
main.c
#include "customer.h"
#include "flight.h"
#include <unistd.h>
int main(int argc, char const *argv[])
{
node_t *list = create_ulist();
if (list == NULL)
{
perror("create_linklist failed\n");
return -1;
}
// printf("list :%p\n",list);
#if 1
nodef_t *head = create_clist();
if (head == NULL)
{
perror("create clist error\n");
return -1;
}
flight_t flight[1000] = {"HB001", "长沙", "北京", 7, 9, 888, 50, 50, "HB002", "长沙", "广州", 8, 9, 588, 50, 48, "HB003", "长沙", "上海", 9, 11, 688, 60, 40, "HB004", "长沙", "西宁", 10, 14, 999, 40, 39, "HB005", "长沙", "南宁", 12, 13, 488, 70, 49};
int i = 0;
for (i = 0; i < 5; i++)
{
insert_hclist(head, flight + i);
putchar(10);
}
int num=0;
// 准备结构体变量 键盘的数据存储起来 并且 插入链表当中
#endif
while (1)
{
C:
showjiemian1(); // 主界面
num=0;
scanf("%d", &num);
getchar();
if (num == 1) // 注册账号
{
user_t user1 = {0};
printf("请输入名字:");
scanf("%s", user1.name);
getchar();
printf("\n");
printf("请输入密码:");
scanf("%d", &user1.code);
getchar();
// 把数据存储进链表
if (!insert_uhlist(list, user1))
{
// showlinklist(list);
// 行缓冲 》 \n 程序结束 fflush 缓冲区满
printf("注册成功请稍等\n");
fflush(stdout);
sleep(3);
system("clear");
A:
showjiemian1();
}
// 提示信息
// 从键盘接受用户名 + 密码
// 比对:findvlist;
}
scanf("%d", &num);
getchar();
if (num == 2) // 普通用户登录
{
if (!usr_login(list))
{
printf("登录成功\n");
printf("\n");
system("clear");
showjiemian3();
while (1)
{
int yonghu = 0; // 从键盘接收数字选择
scanf("%d", &yonghu);
getchar();
#if 1
switch (yonghu)
{
case 1:
system("clear");
printf("请查看航班信息\n");
printf("\n");
printf("航班号 起点 终点 起飞时间 降落时间 航班票价 总票量 剩余票量\n");
print_clist(head);
showjiemian3();
break;
case 2:
printf("请输入终点地址\n"); // 根据终点查询航班
char zhongdian[200] = "";
scanf("%s", zhongdian);
getchar();
flight_t zhongdian2 = {0};
strcpy(zhongdian2.end, zhongdian);
nodef_t *temp1 = find_vclist(head, &zhongdian2, cmpend);
if (temp1 != NULL)
{
system("clear");
printf("您查询的地点航班信息如下\n");
printf("\n");
printf("航班号 起点 终点 起飞时间 降落时间 航班票价 总票量 剩余票量\n");
printf("%s\t%s %s\t%d\t%d\t%d\t %d\t %d\n", temp1->flightdata->id, temp1->flightdata->start, temp1->flightdata->end, temp1->flightdata->tmStart, temp1->flightdata->tmEnd, temp1->flightdata->price, temp1->flightdata->total, temp1->flightdata->left);
showjiemian3();
}
else
{
system("clear");
printf("没有相对应的航班\n");
printf("\n");
showjiemian3();
}
break;
case 3:
goto C;
case 4:
return 0;
default:
printf("输入错误");
break;
}
}
#endif
}
else
printf("账号或密码输入错误\n");
printf("\n");
goto A;
}
while (1)
{
if (num == 3)
{
int a = 0;
printf("请输入管理员密码:\n");
scanf("%d", &a);
if (a == 1234)
{
flight_t hangban1 = {0};
flight_t *flight4 = &hangban1;
system("clear");
B:
showjiemian2(); // 管理员界面
int guanli = 0;
int weizhi = 0;
flight_t hangban2 = {0};
flight_t *flight5 = &hangban2;
scanf("%d", &guanli);
getchar();
switch (guanli) // 输入数字选择选项
{
#if 1
case 1:
system("clear");
printf("请您查看航班信息\n");
printf("\n");
printf("航班号 起点 终点 起飞时间 降落时间 航班票价 总票量 剩余票量\n");
print_clist(head);
goto B;
break;
#endif
case 4: // 修改航班信息
system("clear");
printf("航班号 起点 终点 起飞时间 降落时间 航班票价 总票量 剩余票量\n");
print_clist(head);
printf("\n");
printf("请选择修改第几行航班信息\n");
printf("\n");
scanf("%d", &weizhi);
getchar();
system("clear");
printf("请输入航班号:\n");
scanf("%s", flight5->id);
printf("\n");
printf("请输入起点:\n");
scanf("%s", flight5->start);
printf("\n");
printf("请输入终点:\n");
scanf("%s", flight5->end);
printf("\n");
printf("请输入起飞时间:\n");
scanf("%d", &flight5->tmStart);
printf("\n");
printf("请输入到达时间:\n");
scanf("%d", &flight5->tmEnd);
printf("\n");
printf("请输入航班票价:\n");
scanf("%d", &flight5->price);
printf("\n");
printf("请输入总票量:\n");
scanf("%d", &flight5->total);
printf("\n");
printf("请输入剩余票量:\n");
scanf("%d", &flight5->left);
printf("\n");
if (!updata_ilist(head, weizhi, flight5))
{
system("clear");
printf("修改成功\n");
printf("\n");
printf("航班号 起点 终点 起飞时间 降落时间 航班票价 总票量 剩余票量\n");
show_clist(head, showall);
}
goto B;
break;
#if 1
case 2: // 增加航班信息
printf("请按顺序填写各项航班信息\n");
printf("\n");
printf("请输入航班号:\n");
scanf("%s", flight4->id);
printf("\n");
printf("请输入起点:\n");
scanf("%s", flight4->start);
printf("\n");
printf("请输入终点:\n");
scanf("%s", flight4->end);
printf("\n");
printf("请输入起飞时间:\n");
scanf("%d", &flight4->tmStart);
printf("\n");
printf("请输入到达时间:\n");
scanf("%d", &flight4->tmEnd);
printf("\n");
printf("请输入航班票价:\n");
scanf("%d", &flight4->price);
printf("\n");
printf("请输入总票量:\n");
scanf("%d", &flight4->total);
printf("\n");
printf("请输入剩余票量:\n");
scanf("%d", &flight4->left);
printf("\n");
if (!insert_hclist(head, flight4))
{
// showlinklist(list);
// 行缓冲 》 \n 程序结束 fflush 缓冲区满
system("clear");
printf("添加成功\n");
printf("\n");
printf("航班号 起点 终点 起飞时间 降落时间 航班票价 总票量 剩余票量\n");
show_clist(head, showall);
}
goto B;
break;
#endif
case 3: // 删除航班信息
system("clear");
printf("请输入要删除第几行航班\n");
printf("\n");
printf("航班号 起点 终点 起飞时间 降落时间 航班票价 总票量 剩余票量\n");
print_clist(head);
int hangshu = 0;
flight_t hangshu1 = {0};
scanf("%d", &hangshu);
delete_iclist(head, hangshu, &hangshu1);
system("clear");
printf("航班号 起点 终点 起飞时间 降落时间 航班票价 总票量 剩余票量\n");
show_clist(head, showall);
printf("\n");
printf("删除成功\n");
goto B;
break;
case 5:
system("clear");
showulinklist(list);
goto B;
break;
case 6:
showjiemian4();
printf("\n");
printf("\n");
return 0;
default:
break;
}
}
else
{
system("clear");
printf("密码输入错误:\n");
printf("\n");
goto C;
}
}
}
if (num != 1 || num != 2 || num != 3)
{
printf("输入选项错误\n");
}
}
return 0;
}
用户的.h文件,用来放用户结构体及函数声明
customer.h
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//单链表
//用户名 + 密码
//数据节点
typedef struct user
{
char name[16];
int code;
}user_t;
//元素节点
typedef struct node
{
//数据部分
user_t userdata;
//指针部分
struct node * next;
}node_t;
void showjiemian1(void);
void showjiemian2(void);
void showjiemian3(void);
void showjiemian4(void);
//创建用户链表
node_t* create_ulist();
//插入节点
int insert_uhlist(node_t* head, user_t usertemp);
//3.链表打印函数
void showulinklist(node_t* head);
//查询节点 比较 : 姓名 + 密码 ;
//提示信息:
//查找value所对应的index序号
//比较用户的信息
//第一个为链表中的信息,第二个为页面输入过来的信息
#if 0
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);
#endif
int usr_login(node_t* head);
用户.c文件,主要是一些数据结构单链表一些功能的函数,还有菜单界面,用户登陆界面,以及管理员界面函数。
customer.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include"customer.h"
//单链表
//用户名 + 密码
void showjiemian1(void)
{
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-----------------------------------------------\n");
}
void showjiemian2(void)
{
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-------------------------------------------\n");
}
void showjiemian3(void)
{
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-------------------------------------------\n");
}
void showjiemian4(void)
{
printf("\t\t-------------------------------------------\n");
printf("\t\t 感谢您使用本航班系统 \n");
printf("\t\t 欢迎您下次使用 \n");
printf("\t\t-------------------------------------------\n");
}
//创建用户链表
node_t* create_ulist()
{
//1.申请空间
node_t* newnode =(node_t*)malloc(sizeof(node_t));
if(newnode == NULL)
{
perror("malloc error\n");
return NULL;
}
//2.填写数据 0
bzero(&newnode->userdata,sizeof(user_t));
//3.指针部分 NULL;
newnode->next = NULL;
return newnode;
}
//插入节点
int insert_uhlist(node_t* head, user_t usertemp)
{
//0.合法性检查
if(head == NULL)
{
perror("list is null\n");
return -1;
}
//1.新数据存储工作
node_t* newnode = (node_t*)malloc(sizeof(node_t));
if(newnode == NULL)
{
perror("malloc newnode error\n");
return -2;
}
//合法
newnode-> userdata = usertemp;
//2.头插法的修改指针
newnode->next = head->next; //新节点 指向 数据头
head->next = newnode; //链表头 指向 新节点
return 0 ;
}
//3.链表打印函数
void showulinklist(node_t* head)
{
//0.合法性判断
if(head == NULL)
{
perror("head is error\n");
return ;//代表程序结束
}
//1.定义临时节点 :头节点 不能移动
node_t* temp = head->next;
//temp不空 就打印 temp为空 出界
while(temp != NULL)
{
printf("%s %d\t",temp->userdata.name,temp->userdata.code);
temp = temp->next;
}
//自带换行属性
puts("");
}
//查询节点 比较 : 姓名 + 密码 ;
//提示信息:
//查找value所对应的index序号
//比较用户的信息
//第一个为链表中的信息,第二个为页面输入过来的信息
#if 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 (listUser->code)-(user->code);
}
int cmpUserAll(user_t* listUser, user_t* user)
{
int a, b;
a = strcmp(listUser->name,user->name);
b = (listUser->code)-(user->code);
if(a == 0 && b == 0)
{
return 0;
}
else
return -1;
}
#endif
//用户登录
int usr_login(node_t* head)
{
user_t temp1;
//2.遍历
node_t* temp = head->next;
printf("请输入账号\n");
scanf("%s",temp1.name);
printf("请输入密码\n");
scanf("%d",&temp1.code);
int flag=0; //账号查询成功标志位,1为成功;
while(temp!=NULL)
{
if(strcmp(temp->userdata.name,temp1.name)==0)
{
flag=1;
break;
}
temp=temp->next;
if(flag==0)
{
return -1;
// printf("当前账号不存在\n");
}
else if(flag==1)
{
if(temp->userdata.code != temp1.code)
{
return -2;
// printf("密码错误\n");
}else
// printf("登录成功 \n");
return 0;
}
}
}
航班.h文件,存放航班结构体,以及单向循环链函数声明
flight.h
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//数据节点
typedef struct flight
{
char id[100]; //航班号
char start[200]; //起飞城市
char end[200]; //抵达城市
int tmStart;//起飞时间
int tmEnd; //降落时间
int price; //航班票价
int total;//总票量
int left;//剩余票量
}flight_t;
//元素节点
typedef struct nodef
{
//数据部分
flight_t* flightdata;
//指针部分
struct nodef* next;
}nodef_t;
//定义航班链表
nodef_t* create_clist();
void print_clist(nodef_t* head);
#if 1
//2.头插法 插入数据
int insert_hclist(nodef_t* head,flight_t* newflight);
#endif
int insert_tclist(nodef_t* head,flight_t * flight);
//11.删除第i个元素 。并且把数据传递回来
int delete_iclist(nodef_t* head,int index,flight_t* flight);
//4链表打印函数 :打印部分数据 函数指针
typedef void (*showfun_t)(flight_t* flight);
//打印所有数据
void showall(flight_t* flight);
void show_clist(nodef_t* head,showfun_t showfun);
//替换类型
typedef int (*cmpflightfun_t)(flight_t* flight1,flight_t* flight2);
int cmpend(flight_t* flight1,flight_t* flight2);
//输入终点查询航班
nodef_t* find_vclist(nodef_t* head,flight_t* value,cmpflightfun_t cmpfun);
int updata_ilist(nodef_t* head,int index,flight_t* data);
航班信息.文件,主要是航班信息单向循环链表实现增删改功能的函数
flight.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include"flight.h"
//定义航班链表
nodef_t* create_clist()
{
//1.申请空间
nodef_t* head = (nodef_t*)malloc(sizeof(nodef_t));
if( NULL == head)
{
perror("newnode malloc error\n");
return NULL;
}
//2.填写数据
head->flightdata = NULL;
//单向循环链表只有一个头节点的话,下一个哦节点是自己
head->next = head;
return head;
}
void print_clist(nodef_t* head)
{
//1.循环链表
if(head ==NULL || head->next == head)
{
perror("head is illegal or there is no element\n");
return ;
}
//2.遍历
nodef_t * temp = head->next;
while(temp != head)
{
printf("%s\t%s %s\t%d\t %d\t %d\t %d\t %d\n",temp->flightdata->id,temp->flightdata->start,temp->flightdata->end,temp->flightdata->tmStart,temp->flightdata->tmEnd,temp->flightdata->price,temp->flightdata->total,temp->flightdata->left);
temp =temp->next;
}
puts("");
//temp跳出循环的时候 temp->head;
}
#if 1
//2.头插法 插入数据
int insert_hclist(nodef_t* head,flight_t* newflight)
{
//1
if(head == NULL)
{
perror("head is error\n");
return -1;
}
//2.新申请元素节点 新申请数据节点 关系问题 把数据加进来 连接进入链表
nodef_t* newnode = (nodef_t*)malloc(sizeof(nodef_t));
if(newnode == NULL)
{
perror("newnode malloc error\n");
return -2;
}
newnode->flightdata = malloc(sizeof(flight_t));
if(newnode->flightdata == NULL)
{
perror("newnode->data malloc error\n");
return -3;
}
//数据加入进来
*newnode->flightdata = *newflight;
//3链接进来
newnode->next = head->next;
head->next = newnode;
return 0 ;
}
#endif
int insert_tclist(nodef_t* head,flight_t * flight)
{
if(head == NULL|| flight == NULL)
{
perror("head is null or stu is null\n");
return -1;
}
nodef_t* newnode = malloc(sizeof(nodef_t));
newnode->flightdata = malloc(sizeof(flight_t));
*newnode->flightdata = *flight;
//链接问题
nodef_t* temp = head->next;
while(temp->next!= head)
{
temp =temp->next;
}
newnode->next = temp->next;
temp->next = newnode;
return 0 ;
}
//11.删除第i个元素 。并且把数据传递回来
int delete_iclist(nodef_t* head,int index,flight_t* flight)
{
//1.合法性判断
if(head == NULL || head->next == head )
{
perror("error\n");
return -1;
}
//2.遍历
index = index % 7; // shownode() + 1;
if(index == 0 )
{
perror("index is illegal\n");
return -2;
}
int i = 1 ;
nodef_t * temp = head->next,*before = head;
while(i< index )
{
++i;
before = temp;
temp = temp->next;
}
//3.取出数据
*flight = *temp->flightdata;
//4.修改指针
before->next = temp->next;
free(temp->flightdata);
free(temp);
return 0 ;
}
//4链表打印函数 :打印部分数据 函数指针
typedef void (*showfun_t)(flight_t* flight);
//打印所有数据
void showall(flight_t* flight)
{
printf("%s\t%s %s\t%d\t%d\t%d\t %d\t %d\n",flight->id,flight->start,flight->end,flight->tmStart,flight->tmEnd,flight->price,flight->total,flight->left);
}
void show_clist(nodef_t* head,showfun_t showfun)
{
if(head == NULL || head->next == head)
{
perror("head is illegal or it has no element\n");
return ;
}
//单项循环链表
nodef_t* temp = head->next;
while(temp != head)
{
showfun(temp->flightdata);
temp =temp->next;
}
}
//替换类型
typedef int (*cmpflightfun_t)(flight_t* flight1,flight_t* flight2);
int cmpend(flight_t* flight1,flight_t* flight2)
{
//比较终点
return strcmp(flight1->end,flight2->end);
}
//输入终点查询航班
nodef_t* find_vclist(nodef_t* head,flight_t* value,cmpflightfun_t cmpfun)
{
if(head == NULL || value == NULL)
{
perror("head is null or value is null\n");
return NULL;
}
if(head->next == head)
{
perror("there is no element\n");
return NULL;
}
//遍历
nodef_t * temp = head->next;
while(temp != head) // temp -> next != NULL
{
//把链表中的元素与 外来的元素比较
if(!cmpfun(temp->flightdata,value))
{
return temp;
}
//指针移动
temp = temp->next;
}
return NULL;
}
//修改航班数据
//什么链表 什么数值位置
int updata_ilist(nodef_t* head,int index,flight_t* data)
{
if (head==NULL||index<=0)
{
perror("head is null or index is error\n");
return -1;
}
//2.找到index
int i=0;
nodef_t* temp=head;
while(i<index)
{
++i;
temp=temp->next;
}
temp->flightdata=data;
//3.替换
return 0;
}