1.有一些问题实现不了,需要根据管理员模块Tick.cpp和头文件,用户模块man.cpp和头文件,改写代码实现以下两个问题。(list.h和list.cpp创建链表,插尾节点后),list模块的代码也可以更改,只要实现功能就可以
(1)目前管理员模块代码实现不了显示全部的车次信息,需要实现可以显示全部的火车票信息,并且再做一个可以实现根据车次查询火车票信息的功能。
(2)用户功能中订票目标城市只能查询到一条数据,需要可以显示当订票时查询目标城市后,显示所有到目标城市的车次信息。并改为根据ID删除用户信息而不是姓名。
(可以自己增加查询函数)
以下是代码:
Tick.h
#ifndef __TICKET_H__
#define __TICKET_H__
//定义火车票信息结构体
typedef struct _ticket
{
char number[10]; //火车票的车次
char startCity[10]; //火车票的出发城市
char reachCity[10]; //火车票的到达城市
char takeoffTime[10]; //火车票的出发时间
char reachTime[10]; //火车票的到达时间
float price; //火车票的票价
int ticketNum; //火车票的剩余票数
}ticket;
/************************************* 预 编 译 模 块***************************************************/
#define HEADER1 "|------------------------------book ticket sys--------------------------------| \n"
#define HEADER2 "| number | start city | reach city|takeoffTime| reach time| price| ticketNum | \n"
#define HEADER3 "|-----------------------------------------------------------------------------| \n"
#define FORMAT "|%-10s|%-10s|%-10s|%-11s|%-10s|%-10.2f|%-10d|\n" // 除 了takeoffTime 这一项,为保持上下对齐的美观,其它项数据都固定只占 10 位的长度
extern node * g_ticketList;
//分配内存空间函数
extern void* mallocMemory(int size);
//保存链表中的数据到文件中
extern int saveData(node* head, int size);
//读取文本中的数据到链表中
extern int readData(node* head, int size);
//添加火车票,并保存在火车票信息链表中
extern int addTicket_toList(node* head);
//根据车次,修改火车票,并马上保存在火车票信息链表中
extern int modifyTicket_byNumber(node* head);
//根据车次,删除火车票,并实时更新
extern int deleteTicket_byNumber(node* head);
//显示火车票信息链表中的所有节点数据
extern int showTicketList_allData(node* head);
#endif
Tick.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"
#include "man.h"
#include "tick.h"
node* g_ticketList = NULL;
//分配内存空间函数
void* mallocMemory(int size)
{
if (size == sizeof(ticket))
{
ticket* tmpTicket = (ticket*)malloc(size);
return tmpTicket;
}
else if (size == sizeof(man))
{
man* tmpMan = (man*)malloc(size);
return tmpMan;
}
else
{
printf("error!\n");
return NULL;
}
}
//保存链表中的数据到文件中
int saveData(node* head, int size)
{
FILE* fp = NULL;
int ret = 0;
if (size == sizeof(ticket))
fopen_s(&fp, "ticket.txt", "wb"); //打开一个只写的二进制文本
else if (size == sizeof(man))
fopen_s(&fp, "man.txt", "wb"); //打开一个只写的二进制文本
if (!fp)
{
printf("fopen error!\n");
return -1;
}
void* temp = NULL;
for (node* cur = head->next; cur != NULL; cur = cur->next)
{
if (size == sizeof(ticket))
temp = (ticket*)cur->dat; //获取链表节点保存的数据
else if (size == sizeof(man))
temp = (man*)cur->dat; //获取链表节点保存的数据
ret = fwrite(temp, size, 1, fp); //将结构体数据写入二进制文本
if (ret != 1)
{
printf("fwrite error!\n");
return -1;
}
}
fclose(fp);
printf("fwrite success!\n");
return 0;
}
//读取文本中的数据到链表中
int readData(node* head, int size)
{
FILE* fp = NULL;
if (size == sizeof(ticket))
fopen_s(&fp, "ticket.txt", "rb"); //打开一个只读的二进制文本
else if (size == sizeof(man))
fopen_s(&fp, "man.txt", "rb"); //打开一个只读的二进制文本
if (!fp)
{
printf("fopen error!\n");
return -1;
}
void* temp = NULL;
while (!feof(fp))
{
if (size == sizeof(ticket))
temp = (ticket*)mallocMemory(sizeof(ticket)); //定义一个临时火车票结构体指针(必须定义在 while 内,每次读文件,都必须重新分配内存空间)
else if (size == sizeof(man))
temp = (man*)mallocMemory(sizeof(man)); //定义一个临时订票人结构体指针(必须定义在 while 内,每次读文件,都必须重新分配内存空间)
if (fread(temp, size, 1, fp) == 1) //读取二进制文本的结构体数据
{
insertData_toListTail(head, temp); //插入数据到链表尾节点后
}
}
fclose(fp);
printf("fread success!\n");
return 0;
}
/**********************************
man.h
#ifndef __MAN_H__
#define __MAN_H__
//定义订票人结构体
typedef struct _man
{
int ID; //ID 身份证号码
char name[10]; //名字
int bookNum; //订票数目
}man;
extern node* g_manList; //外部声明一个全局订票人信息链表
//显示订票人信息链表中的所有节点数据
extern int showManList_allData(node* head);
//订票函数
extern int bookTicket(node* head);
//根据名字删除用户信息
extern int deleteMan(node* head, int name);
#endif
man.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"
#include "tick.h"
#include "man.h"
node* g_manList = NULL; //定义一个全局订票人信息链表
//显示订票人信息链表中的所有节点数据
int showManList_allData(node* head)
{
if (!head->next) //检测链表是否只有一个节点
{
printf("list only have one node,error!\n"); //链表只有一个节点,则打印错误信息,并返回
return -1;
}
man* tmpMan = NULL; //定义订票人信息的临时结构体指针
for (node* cur = head->next; cur != NULL; cur = cur->next) //由于头节点不保存数据,所以从第二个节点开始显示数据
{
tmpMan = (man*)cur->dat; //将节点数据取出来,赋给临时结构体指针
printf("%d %s %d\n", tmpMan->ID, tmpMan->name, tmpMan->bookNum);
}
return 0;
}
//订票函数
int bookTicket(node* head)
{
bool findTicket_flag = false; //找到车次对应火车票的标志位
if (!g_ticketList->next) //检测火车票信息链表是否只有一个节点
{
printf("g_ticketList only have one node,error!\n"); //链表只有一个节点,则打印错误信息,并返回
return -1;
}
char t_reachCity[10];
printf("请输入你要去的城市:");
scanf_s("%s", t_reachCity, 10);
ticket* tmpTicket = NULL;
node* cur;
for (cur = head->next; cur != NULL; cur = cur->next)
{
tmpTicket = (ticket*)cur->dat; //获取火车票信息链表节点保存的数据
if (strcmp(t_reachCity, tmpTicket->reachCity) == 0 ) //检查输入城市对应的火车票是否存在,````始发,终点
{
findTicket_flag = true;
printf(FORMAT, tmpTicket->number, tmpTicket->startCity,tmpTicket->reachCity, tmpTicket->takeoffTime, tmpTicket->reachTime, tmpTicket->price,tmpTicket->ticketNum);
break;
}
}
if (!findTicket_flag)
{
printf("the number isn't exist!\n");
return -1;
}
char cmd;
printf("Do you want book ticket?(y/n): ");
getchar(); //吸收上次输入的"ENTER"
scanf_s("%c", &cmd, 10);
if (cmd == 'y')
{
;
}
else if (cmd == 'n')
{
return -1;
}
else
{
printf("cmd error!\n");
return -1;
}
man* tmpMan = (man*)mallocMemory(sizeof(man)); //定义一个临时订票人结构体指针,并分配内存空间
printf("请输入你的 ID:");
scanf_s("%d", &tmpMan->ID);
printf("请输入你的姓名:");
scanf_s("%s", tmpMan->name, 10);
printf("请输入你的订票数目:");
scanf_s("%d", &tmpMan->bookNum);
//更新该车次火车票的剩余票数
tmpTicket->ticketNum -= tmpMan->bookNum;
cur->at = tmpTicket;
insertData_toListTail(g_manList, tmpMan); //插入订票人数据到链表尾节点后
printf("book ticket success!\n");
saveData(g_manList, sizeof(man));
return -1;
}
//删除用户信息
int deleteMan(node* head,int name)
{
bool findman_flag = false;
if (!head->next) //检测链表是否只有一个节点
{
printf("list only have one node,error!\n"); //链表只有一个节点,则打印错误信息,并返回
return -1;
}
char t_name[10];
printf("请输入要删除的名字:");
scanf_s("%s", t_name, 10);
man* tmpman = NULL;
for (node* lastNode = head; lastNode->next != NULL; lastNode = lastNode->next)
{
tmpman = (man*)lastNode->next->dat; //获取火车票信息链表节点保存的数据
if (strcmp(t_name, tmpman->name) == 0) //检查输入车次对应的火车票是否存在
{
findman_flag = true;
node* deleteNode = lastNode->next; //“要删除节点”deleteNode,为“上个节点”lastNode 的 next 节点
lastNode->next = deleteNode->next; //“上个节点”的 next 指向“要删除节点”的 next,则相当于删除了“要删除节点”
free(deleteNode->dat);
free(deleteNode); //后面要用到 deleteNode,所以不能释放,否则会崩溃
printf("delete man success!\n");
saveData(g_manList, sizeof(man)); //保存火车票链表中的信息到文件中
break;
}
}
if (!findman_flag)
{
printf("the name isn't exist!\n");
return -1;
}
return 0;
}
list.h
#ifndef __LIST_H__
#define __LIST_H__
//定义单向链表节点
typedef struct node
{
void* dat; //一般为结构体指针
int size; //dat 指向区域的大小,一般为结构体的大小
struct node* next; //后继节点
}node;
//创建链表
extern node* createList(int size);
//插入数据到链表尾节点后
extern int insertData_toListTail(node* head, void* dat);
#endif
list.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"
#include "tick.h"
#include "man.h"
//创建链表
node* createList(int size)
{
node* head = (node*)malloc(sizeof(node)); //给链表头结点分配内存空间
if (!head)
{
printf("listHead malloc error!\n");
return NULL;
}
head->dat = NULL; //链表头结点不存储数据,故指向 NULL
head->size = size; //链表的 size 一般为结构体的大小[size == sizeof(ticket)]
head->next = NULL;
return head;
}
//插入数据到链表尾节点后
int insertData_toListTail(node* head, void* dat)
{
node* tmpNode = (node*)malloc(sizeof(node)); //定义一个存储插入数据的临时节点,插入该节点就相当于插入数据了
if (!tmpNode)
{
printf("tmpNode malloc error!\n");
return NULL;
}
//给临时节点的数据指针 dat 分配内存空间
tmpNode->dat = malloc(sizeof(head->size)); //dat 的类型一般为 struct *,所以不再进行(void*)的强制类型转换
if (!tmpNode->dat)
{
printf("tmpNode->dat malloc error!\n");
return NULL;
}
tmpNode->dat = dat; //将要插入的数据保存在临时节点内
tmpNode->size = head->size;
struct node* cur = head; //定义当前节点
while (cur->next=NULL) //找到尾节点 [若链表只有一个头节点,则头节点就是尾节点]
{
node*cur =(node*)cur->next;
}
//将保存要插入数据的临时节点,插入到尾节点后
cur->next = tmpNode;
tmpNode->next = NULL; //此时,tmpNode 变为尾节点
saveData(g_ticketList, sizeof(ticket));
return 0;
}
【以下回答由 GPT 生成】
根据问题描述,我们需要对火车票订票系统的代码进行优化和功能改进,包括添加显示全部火车票信息的功能,根据车次查询火车票信息的功能,显示所有到目标城市的车次信息的功能,以及修改订票系统让删除用户信息通过ID进行操作。
下面是针对这些需求的代码优化和功能改进:
// 显示全部的火车票信息
int displayAllTickets() {
printf(HEADER1);
printf(HEADER2);
printf(HEADER3);
node *current = g_ticketList;
while (current != NULL) {
ticket *currentTicket = (ticket*)current->data;
printf(FORMAT, currentTicket->number, currentTicket->startCity, currentTicket->reachCity, currentTicket->takeoffTime, currentTicket->reachTime, currentTicket->price, currentTicket->ticketNum);
current = current->next;
}
return 0;
}
// 根据车次查询火车票信息
int searchTicketByNumber(char *number) {
printf(HEADER1);
printf(HEADER2);
printf(HEADER3);
node *current = g_ticketList;
while (current != NULL) {
ticket *currentTicket = (ticket*)current->data;
if (strcmp(currentTicket->number, number) == 0) {
printf(FORMAT, currentTicket->number, currentTicket->startCity, currentTicket->reachCity, currentTicket->takeoffTime, currentTicket->reachTime, currentTicket->price, currentTicket->ticketNum);
return 0;
}
current = current->next;
}
printf("Ticket not found.\n");
return -1;
}
// 显示所有到目标城市的车次信息
int displayTicketsToCity(char *city) {
printf(HEADER1);
printf(HEADER2);
printf(HEADER3);
node *current = g_ticketList;
while (current != NULL) {
ticket *currentTicket = (ticket*)current->data;
if (strcmp(currentTicket->reachCity, city) == 0) {
printf(FORMAT, currentTicket->number, currentTicket->startCity, currentTicket->reachCity, currentTicket->takeoffTime, currentTicket->reachTime, currentTicket->price, currentTicket->ticketNum);
}
current = current->next;
}
return 0;
}
// 根据ID删除用户信息
int deleteUserInfoById(int id) {
node *current = g_ticketList;
node *previous = NULL;
while (current != NULL) {
ticket *currentTicket = (ticket*)current->data;
if (currentTicket->id == id) {
if (previous == NULL) {
g_ticketList = current->next;
} else {
previous->next = current->next;
}
free(current);
return 0;
}
previous = current;
current = current->next;
}
printf("Ticket not found.\n");
return -1;
}
补全代码如下:
#include "list.h"
//定义火车票信息结构体
typedef struct _ticket
{
int id; //火车票的ID
char number[10]; //火车票的车次
char startCity[10]; //火车票的出发城市
char reachCity[10]; //火车票的到达城市
char takeoffTime[10]; //火车票的出发时间
char reachTime[10]; //火车票的到达时间
float price; //火车票的票价
int ticketNum; //火车票的剩余票数
} ticket;
/************************************* 预 编 译 模 块***************************************************/
#define HEADER1 "|------------------------------book ticket sys--------------------------------| \n"
#define HEADER2 "| id | number | start city | reach city|takeoffTime| reach time| price| ticketNum | \n"
#define HEADER3 "|-----------------------------------------------------------------------------| \n"
#define FORMAT "|%-3d|%-10s|%-10s|%-10s|%-11s|%-10s|%-10.2f|%-10d|\n" // 除了takeoffTime 这一项,为保持上下对齐的美观,其它项数据都固定只占 10 位的长度
extern node *g_ticketList;
//分配内存空间函数
extern void *mallocMemory(int size);
//保存链表中的数据到文件中
extern int saveData(node *head, int size);
//读取文本中的数据到链表中
extern int readData(node *head, int size);
//添加火车票,并保存在火车票信息链表中
extern int addTicketToList(ticket newTicket);
//显示全部的火车票信息
extern int displayAllTickets();
//根据车次查询火车票信息
extern int searchTicketByNumber(char *number);
//显示所有到目标城市的车次信息
extern int displayTicketsToCity(char *city);
//根据ID删除用户信息
extern int deleteUserInfoById(int id);
// 显示全部的火车票信息
int displayAllTickets() {
printf(HEADER1);
printf(HEADER2);
printf(HEADER3);
node *current = g_ticketList;
while (current != NULL) {
ticket *currentTicket = (ticket*)current->data;
printf(FORMAT, currentTicket->id, currentTicket->number, currentTicket->startCity, currentTicket->reachCity, currentTicket->takeoffTime, currentTicket->reachTime, currentTicket->price, currentTicket->ticketNum);
current = current->next;
}
return 0;
}
// 根据车次查询火车票信息
int searchTicketByNumber(char *number) {
printf(HEADER1);
printf(HEADER2);
printf(HEADER3);
node *current = g_ticketList;
while (current != NULL) {
ticket *currentTicket = (ticket*)current->data;
if (strcmp(currentTicket->number, number) == 0) {
printf(FORMAT, currentTicket->id, currentTicket->number, currentTicket->startCity, currentTicket->reachCity, currentTicket->takeoffTime, currentTicket->reachTime, currentTicket->price, currentTicket->ticketNum);
return 0;
}
current = current->next;
}
printf("Ticket not found.\n");
return -1;
}
// 显示所有到目标城市的车次信息
int displayTicketsToCity(char *city) {
printf(HEADER1);
printf(HEADER2);
printf(HEADER3);
node *current = g_ticketList;
while (current != NULL) {
ticket *currentTicket = (ticket*)current->data;
if (strcmp(currentTicket->reachCity, city) == 0) {
printf(FORMAT, currentTicket->id, currentTicket->number, currentTicket->startCity, currentTicket->reachCity, currentTicket->takeoffTime, currentTicket->reachTime, currentTicket->price, currentTicket->ticketNum);
}
current = current->next;
}
return 0;
}
// 根据ID删除用户信息
int deleteUserInfoById(int id) {
node *current = g_ticketList;
node *previous = NULL;
while (current != NULL) {
ticket *currentTicket = (ticket*)current->data;
if (currentTicket->id == id) {
if (previous == NULL) {
g_ticketList = current->next;
} else {
previous->next = current->next;
}
free(current);
return 0;
}
previous = current;
current = current->next;
}
printf("Ticket not found.\n");
return -1;
}