Skip to content

Instantly share code, notes, and snippets.

@gitzhou
Created September 6, 2015 15:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gitzhou/4d3e4d54ae9b7671b13c to your computer and use it in GitHub Desktop.
Save gitzhou/4d3e4d54ae9b7671b13c to your computer and use it in GitHub Desktop.
北方工业大学-计算机系-大一-小学期-冰鞋管理系统-C代码
//
// skate-shoes-rent-system
//
// Created by aaron67 on 15/9/6.
// Copyright (c) 2015年 aaron67. All rights reserved.
//
// Mac OS X Yosemite环境测试可用
// 在可执行文件相同路径下,新建文件
// - rent.dat
// - shoes.dat
// - count.dat
// - number.dat
// - password.dat
// 初次运行,先查看 short CheckPassword();
// 了解初始化密码的方式。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/***************************** 模 型 设 计 ***********************************/
// 字符串最大长度
#define STRING_MAX_SIZE 1024
// 冰鞋类型
// Speed 速滑冰鞋
// Synchronise 花样冰鞋
typedef enum ShoeType {Speed = 0, Synchronise = 1} ShoeType;
// 字符串类型
typedef struct String
{
char string[STRING_MAX_SIZE]; // 字符数组
unsigned long length; // 字符串有效长度
} String;
// 日期类型
typedef struct Date
{
int year; // 年
int month; // 月
int day; // 日
String string; // 字符串形式
} Date;
// 时间类型
typedef struct Time
{
int hour; // 时
int minute; // 分
int second; // 秒
String string; // 字符串形式
} Time;
// 冰鞋详细信息
// 对应 shoes.dat
typedef struct SkateShoe
{
String key_number; // 编码
ShoeType type; // 类型
double size; // 鞋号
String color; // 颜色
String brand; // 品牌
double unit_price; // 单价
String manufacturer; // 厂家
short rent_status; // 租用状态 1 表示已租用
short remark; // 说明 1 表示需要维修
short status; // 标记该条记录是否有效 1 表示有效
} SkateShoe;
// 冰鞋数量信息
// 对应 number.dat
typedef struct ShoeNumber
{
double shoe_size; // 鞋号
ShoeType shoe_type; // 冰鞋类型
int total_quantity; // 总数量
int left_quantity; // 剩余数量
short status; // 标记该条记录是否有效 1 表示有效
} ShoeNumber;
// 冰鞋租用详细信息
// 对应 rent.dat
typedef struct RentDetails
{
String user_name; // 姓名
String id_number; // 身份证号
String contact_info; // 联系方式
double shoe_size; // 鞋号
String shoe_key_number; // 冰鞋编码
ShoeType shoe_type; // 冰鞋类型
Date date; // 日期
Time rent_time; // 起始日期
double deposit; // 押金
double rent_price_per_hour; // 每小时租金
short status; // 标记该条记录是否有效 1 表示有效
} RentDetails;
// 冰鞋归还详细信息
// 对应 count.dat
typedef struct BackDetails
{
Date back_date; // 归还日期
double shoe_size; // 鞋号
ShoeType shoe_type; // 冰鞋类型
double lend_hours; // 租用时间
double rent_price_per_hour; // 每小时租金
double total_cost; // 总花费
} BackDetails;
/***************************** 函 数 声 明 ***********************************/
/************************* 类 Sring 函 数 声 明 ******************************/
// String 对象初始化
void StringInit(String *str);
// 从控制台向 String 类对象 *str 中输入数据
void StringInput(String *str);
// 比较两个 String 类对象 str 和 target
// 程序返回值
// 等于 0 str = target
// 大于 0 str > target
// 小于 0 str < target
short StringCompare(String str, String target);
// 返回 String 类对象 str 的有效长度
unsigned long StringLength(String str);
// 将 String 类对象 from 拷贝到 *str 中
void StringCopy(String *str, String from);
// 将字符串 sz 拷贝到 String 类对象 *str 中
void StringCopyFromCharArray(String *str, char *sz);
// 返回 String 类对象 str 中字符数组的指针
char *StringGetString(String *str);
/************************ 类 Date 类 Time 函 数 声 明 ************************/
// 输入日期
void DateInput(Date *date);
// 输入时间
void TimeInput(Time *time);
// 返回 date 表示日期的字符串
char *DateGetString(Date date);
// 返回 time 表示时间的字符串
char *TimeGetString(Time time);
// 计算两个时间的差
// 程序返回小时数
// 返回 -1 表示错误
double CalculateHours(Time st, Time et);
// 比较 date 和 target 的大小
// 1 date > target
// 0 date = target
// -1 date < target
short DateCompare(Date date, Date target);
// 比较 time 和 target 的大小
// 1 time > target
// 0 time = target
// -1 time < target
short TimeCompare(Time time, Time target);
/*************************** 主 系 统 函 数 声 明 ****************************/
// 显示欢迎画面
void ShowHello();
// 冰鞋租用
void RentShoes();
// 冰鞋归还
void BackShoes();
// 数据维护
void DataModify();
// 密码修改
void PasswordModify();
// 综合查询
void GeneralQuery();
// 退出主系统
void QuitMainSystem();
/******************** 数 据 维 护 子 系 统 函 数 声 明 ***********************/
// 新增冰鞋数据
void AddShoes();
// 更新冰鞋数据
void UpdateShoes();
// 删除冰鞋数据
void DeleteShoes();
// 退出数据维护子系统
void QuitDataModifySystem();
/******************** 综 合 查 询 子 系 统 函 数 声 明 ***********************/
// 打印全部信息
void DisplayAllFiles();
// 查询统计
void Query();
// 退出综合查询子系统
void QuitGeneralQuerySystem();
/********************** 冰 鞋 租 还 处 理 函 数 声 明 ************************/
// 将记录 rd 写入文件 rent.dat
// append = 1 则追加写入 否则在下标 pos 指示的相对位置写入 程序返回
// 0 写入成功
// -1 打开文件错误
// -2 未知错误
short RentDetailsWrite2File(RentDetails rd, int pos, short append);
// 将记录 bd 写入文件 count.dat
// append = 1 则追加写入 否则在下标 pos 指示的相对位置写入 程序返回
// 0 写入成功
// -1 打开文件错误
// -2 未知错误
short BackDetailsWrite2File(BackDetails bd, int pos, short append);
// 根据用户姓名 user_name 身份证号 id_number 冰鞋编号 key_number
// 在文件 rent.dat 中查找相应记录 程序返回
// >= 0 记录在文件中的下标
// -3 查找不成功
// -1 文件打开错误
// -2 未知错误
int FindRentRecord(String user_name, String id_number, String key_number, RentDetails *rd);
/******************** 查 询 统 计 子 系 统 函 数 声 明 ***********************/
// 查询冰鞋信息
void QueryShoes();
// 根据查询条件从文件 shoe.dat 中查询符合条件的记录 程序返回
// 0 没有符合条件的记录
// 1 有符合条件的记录
// -1 文件打开错误
short QueryShoesFromFile(String key_number, String type, String size,
String color, String brand, String manufacturer,
String rent_status, String remark);
// 查询数量信息
void QueryNumber();
// 根据查询条件从文件 number.dat 中查询符合条件的记录 程序返回
// 0 没有符合条件的记录
// 1 有符合条件的记录
// -1 文件打开错误
short QueryNumberFromFile(String shoe_size, String shoe_type, String total_quantity, String left_quantity);
// 查询租用信息
void QueryRentDetails();
// 根据查询条件从文件 rent.dat 中查询符合条件的记录 程序返回
// 0 没有符合条件的记录
// 1 有符合条件的记录
// -1 文件打开错误
short QueryRentDetailsFromFile(String user_name, String id_number, String size, String date);
// 计算当日收入
void CalculateIncome();
// 退出查询统计子系统
void QuitQuerySystem();
// 显示查询结果列表表头
void DisplayQueryTitle();
// 同时统计结果列表表头
void DisplayStatisticsTitle();
/**************************** 打 印 函 数 声 明 ******************************/
// 打印 shoes.dat 程序返回
// 0 没有符合条件的记录
// 1 有符合条件的记录
// -1 文件打开错误
short DisplayShoes();
// 打印 number.dat 程序返回
// 0 没有符合条件的记录
// 1 有符合条件的记录
// -1 文件打开错误
short DisplayNumber();
// 打印 rent.dat 程序返回
// 0 没有符合条件的记录
// 1 有符合条件的记录
// -1 文件打开错误
short DisplayRent();
// 打印 count.dat 程序返回
// 0 没有符合条件的记录
// 1 有符合条件的记录
// -1 文件打开错误
short DisplayCount();
// 打印计费单据
void DisplayCostDetails(BackDetails bd);
/********************** 冰 鞋 数 据 处 理 函 数 声 明 ************************/
// 冰鞋详细信息对象初始化
void SkateShoeInit(SkateShoe *ss);
// 冰鞋数量信息对象初始化
void ShoeNumberInit(ShoeNumber *sn);
// 租用详细信息对象初始化
void RentDetailsInit(RentDetails *rd);
// 设置 SkateShoe 对象 *ss 的值
// UpdateShoes() 为 1 表示是在更新记录 此时不用输入编号
// 成功返回 0
// 失败返回 -1
short GetShoeData(SkateShoe *ss, short update);
// 将记录 ss 写入文件 shoes.dat
// append = 1 则追加写入 否则在下标 pos 指示的相对位置写入 返回
// 0 写入成功
// -1 打开文件错误
// -2 未知错误
short ShoesWrite2File(SkateShoe ss, long pos, short append);
// 通过编号 key 查找冰鞋信息
// >=0 查找成功 返回的是记录在文件中的下标
// -3 查找失败
// -1 文件打开错误
int FindShoesByKey(String key, SkateShoe *ss);
// 新增冰鞋数据时显示生成的标签
void DisplayLabel(SkateShoe ss);
/*********************** 冰 鞋 数 量 维 护 函 数 声 明 ***********************/
// 在新增冰鞋数据时更新数量文件 number.dat
// flag_back = 1 时表明是 UpdateNumberWhenBackShoes() 调用
void UpdateNumberWhenAddShoes(SkateShoe ss, short flag_back);
// 在删除冰鞋数据时更新数量文件 number.dat
// flag_rent = 1 时表明是 UpdateNumberWhenRentShoes() 调用
void UpdateNumberWhenDeleteShoes(SkateShoe ss, short flag_rent);
// 在更新冰鞋数据时更新数量文件 number.dat
void UpdateNumberWhenUpdateShoes(SkateShoe old_ss, SkateShoe new_ss);
// 在租用冰鞋时更新数量文件 number.dat
void UpdateNumberWhenRentShoes(SkateShoe ss);
// 在退租冰鞋时更新数量文件 number.dat
void UpdateNumberWhenBackShoes(SkateShoe ss);
// 向文件 number.dat 中写入一条记录
// append = 1 则追加写入
// 否则在下标 pos 指示的相对位置写入
// 0 写入成功
// -1 文件打开错误
// -2 未知错误
short NumberWrite2File(ShoeNumber sn, int pos, short append);
// 根据鞋号和冰鞋类型在 number.dat 文件中找到记录的下标并返回
// >0 查找成功
// -3 查找失败
// -1 文件打开错误
int FindNumberRecord(double shoe_size, ShoeType st, ShoeNumber *sn);
/************************** 密 码 处 理 函 数 声 明 **************************/
// 初始化密码为 gitzhou
void InitPassword();
// 更新密码为 str 返回
// 0 更新成功
// -1 文件打开错误
// -2 未知错误
short UpdatePassword(String str);
// 处理密码输入的同时在控制台上显示星号
void InputPassword(String *str);
// 检测用户输入的密码是否正确 返回
// 2 密码初始化成功
// 1 密码正确
// 0 密码错误
// -1 文件打开错误
// -2 未知错误
short CheckPassword();
/**************************** 菜 单 函 数 声 明 ******************************/
// 显示程序主菜单
void ShowMainMenu();
// 显示数据维护菜单
void ShowDataModifyMenu();
// 显示综合查询菜单
void ShowGeneralQueryMenu();
// 显示查询统计菜单
void ShowQueryMenu();
/******************************** 程 序 入 口 ********************************/
int main()
{
short pwd_check; // 密码匹配结果
ShowHello(); // 显示欢迎画面
// 检测密码匹配情况
if((pwd_check = CheckPassword()) == 1 || pwd_check == 2)
{
// 通过
printf("\n\n");
ShowMainMenu();
}
else if(pwd_check == 0)
{
// 未通过
printf("\n\n\a密码输入错误,程序结束!\n");
QuitMainSystem();
}
else
{
// 未知错误
printf("\n\n\a未知错误,程序结束!\n");
QuitMainSystem();
}
return 0;
}
/***************************** 函 数 实 现 ***********************************/
/************************* 类 Sring 函 数 实 现 ******************************/
// String 对象初始化
void StringInit(String *str)
{
(str->string)[0] = 0;
str->length = 0;
}
// 从控制台向 String 类对象 *str 中输入数据
void StringInput(String *str)
{
gets(str->string);
str->length = strlen(str->string);
}
// 比较两个 String 类对象 str 和 target
// 程序返回值
// 等于 0 str = target
// 大于 0 str > target
// 小于 0 str < target
short StringCompare(String str, String target)
{
return strcmp(str.string, target.string);
}
// 返回 String 类对象 str 的有效长度
unsigned long StringLength(String str)
{
return str.length;
}
// 将 String 类对象 from 拷贝到 *str 中
void StringCopy(String *str, String from)
{
strcpy(str->string, from.string);
str->length = from.length;
}
// 将字符串 sz 拷贝到 String 类对象 *str 中
void StringCopyFromCharArray(String *str, char *sz)
{
strcpy(str->string, sz);
str->length = strlen(sz);
}
// 返回 String 类对象 str 中字符数组的指针
char *StringGetString(String *str)
{
return str->string;
}
/************************ 类 Date 类 Time 函 数 实 现 ************************/
// 输入日期
void DateInput(Date *date)
{
char str[STRING_MAX_SIZE];
scanf("%d/%d/%d", &(date->year), &(date->month), &(date->day));
// 拼装字符串 拼完后格式为 年/月/日
sprintf(str, "%d/%d/%d", date->year, date->month, date->day);
// 赋值
StringCopyFromCharArray(&(date->string), str);
}
// 输入时间
void TimeInput(Time *time)
{
char str[STRING_MAX_SIZE];
scanf("%d-%d", &(time->hour), &(time->minute));
time->second = 0;
// 拼装字符串 拼完后格式为 时:分
sprintf(str, "%d-%d", time->hour, time->minute);
// 赋值
StringCopyFromCharArray(&(time->string), str);
}
// 返回 date 表示日期的字符串
char *DateGetString(Date date)
{
return StringGetString(&date.string);
}
// 返回 time 表示时间的字符串
char *TimeGetString(Time time)
{
return StringGetString(&time.string);
}
// 计算两个时间的差
// 程序返回小时数
// 返回 -1 表示错误
double CalculateHours(Time st, Time et)
{
double d_ansr; // 时间差计算结果
int i_ansr; // 中间变量
short fn_retn_value; // 存放调用 TimeCompare() 函数的返回值
if((fn_retn_value = TimeCompare(et, st)) < 0)
{
// 终止时间 < 起始时间
printf("\n\a出错!\n");
return -1;
}
else if(fn_retn_value == 0)
{
// 终止时间 = 起始时间
return 0.0;
}
// 终止时间 > 起始时间
// 计算时间差 取小数点后一位
d_ansr = ((et.hour - st.hour) * 60 + et.minute - st.minute) / 60.0;
i_ansr = (int)(d_ansr * 10);
d_ansr = i_ansr / 10.0;
return d_ansr;
}
// 比较 date 和 target 的大小
// 1 date > target
// 0 date = target
// -1 date < target
short DateCompare(Date date, Date target)
{
// 比较 年
if(date.year > target.year)
{
return 1;
}
else if(date.year < target.year)
{
return -1;
}
else
{
// 比较 月
if(date.month > target.month)
{
return 1;
}
else if(date.month < target.month)
{
return -1;
}
else
{
// 比较 日
if(date.day > target.day)
{
return 1;
}
else if(date.day < target.day)
{
return -1;
}
else
{
return 0;
}
}
}
}
// 比较 time 和 target 的大小
// 1 time > target
// 0 time = target
// -1 time < target
short TimeCompare(Time time, Time target)
{
// 比较 时
if(time.hour > target.hour)
{
return 1;
}
else if(time.hour < target.hour)
{
return -1;
}
else
{
// 比较 分
if(time.minute > target.minute)
{
return 1;
}
else if(time.minute < target.minute)
{
return -1;
}
else
{
// 比较 秒
if(time.second > target.second)
{
return 1;
}
else if(time.second < target.second)
{
return -1;
}
else
{
return 0;
}
}
}
}
/*************************** 主 系 统 函 数 实 现 ****************************/
// 显示欢迎画面
void ShowHello()
{
printf("\n");
printf("-------------------------------------------------------------------------------\n");
printf("| 欢 迎 使 用 冰 鞋 租 用 管 理 系 统 |\n");
printf("-------------------------------------------------------------------------------\n");
}
// 冰鞋租用
void RentShoes()
{
ShoeNumber sn; // 冰鞋数量对象
SkateShoe ss; // 冰鞋信息对象
RentDetails rd; // 租用信息对象
int pos_sn; // 存放相应数量记录在文件中的下标
int pos_ss; // 存放相应冰鞋记录在文件中的下标
int flag_rent_continue = 1; // 标记 为 1 表示继续租用其它冰鞋
String input_option; // 存放用户选择是否继续的输入
double shoe_size; // 鞋号
ShoeType shoe_type; // 冰鞋类型
String input_type; // 用户输入的鞋号
String input_size; // 用户输入的冰鞋类型
// 常量 String 对象
String null;
String rent_status_0;
StringCopyFromCharArray(&null, "null");
StringCopyFromCharArray(&rent_status_0, "0");
// 初始化各对象
ShoeNumberInit(&sn);
SkateShoeInit(&ss);
RentDetailsInit(&rd);
StringInit(&input_type);
StringInit(&input_size);
StringInit(&input_option);
while(flag_rent_continue)
{
// 输入查询的鞋号
printf("\n请输入要租用的冰鞋鞋号: ");
StringInput(&input_size);
if(StringLength(input_size) == 0)
{
printf("\n\a输入有误!\n");
return;
}
shoe_size = atof(StringGetString(&input_size));
// 输入查询的冰鞋类型
printf("请选择冰鞋的类型,0 -> 速滑冰鞋 1 -> 花样冰鞋: ");
StringInput(&input_type);
if(strcmp(StringGetString(&input_type), "0") != 0 &&
strcmp(StringGetString(&input_type), "1") != 0)
{
printf("\n\a输入有误!\n");
return;
}
shoe_type = atoi(StringGetString(&input_type));
// 取到对应的数量记录
if((pos_sn = FindNumberRecord(shoe_size, shoe_type, &sn)) >= 0)
{
if(sn.left_quantity == 0)
{
// 没有余鞋
printf("\n\a抱歉,没有余鞋!\n");
}
else
{
// 有余鞋 可以租用
// 显示可租的冰鞋列表
DisplayQueryTitle();
QueryShoesFromFile(null, input_type, input_size, null, null, null, rent_status_0, null);
// 生成 RentDetails 对象
if(flag_rent_continue == 1)
{
// flag_rent_continue = 1 表明是用户第一次输入个人信息
// 输入姓名
printf("请输入您的姓名: ");
StringInput(&(rd.user_name));
if(StringLength(rd.user_name) == 0)
{
printf("\n\a输入错误!\n");
return;
}
// 输入身份证号
printf("身份证号: ");
StringInput(&(rd.id_number));
if(StringLength(rd.id_number) == 0)
{
printf("\n\a输入错误!\n");
return;
}
// 输入联系方式
printf("联系方式: ");
StringInput(&rd.contact_info);
if(StringLength(rd.contact_info) == 0)
{
printf("\n\a输入错误!\n");
return;
}
// 更新标记
++flag_rent_continue;
}
// 冰鞋编号
printf("待租用冰鞋编号: ");
StringInput(&rd.shoe_key_number);
if(StringLength(rd.shoe_key_number) == 0)
{
printf("\n\a输入错误!\n");
return;
}
// RentDetails 对象记录生成完毕
// 取出对应的冰鞋记录
if((pos_ss = FindShoesByKey(rd.shoe_key_number, &ss)) >= 0)
{
// 存在对应的冰鞋记录
if(ss.rent_status == 0)
{
// 冰鞋未被租用
rd.shoe_size = ss.size; // 鞋号
rd.shoe_type = ss.type; // 冰鞋类型
// 输入日期
printf("\n租用日期,格式 年/月/日: ");
DateInput(&(rd.date));
// 输入时间
printf("租用时间,格式 时-分: ");
TimeInput(&(rd.rent_time));
// 更新 shoes.dat 文件
ss.rent_status = 1;
if(ShoesWrite2File(ss, pos_ss, 0) != 0)
{
printf("\n\a未知错误!\n");
return;
}
//更新 rent.dat 文件
RentDetailsWrite2File(rd, 0, 1);
// 更新 number.dat 文件
UpdateNumberWhenRentShoes(ss);
}
else
{
// 冰鞋已被租用
printf("\n\a此编号的冰鞋已被租用!\n");
}
}
else if(pos_ss == -3)
{
// 不存在这种编号的冰鞋
printf("\n\a没有此编号的冰鞋!\n");
}
else
{
// 位置错误
printf("\n\a未知错误!\n");
return;
}
}
}
else if(pos_sn == -3)
{
// 无符合要求的冰鞋
printf("\n\a没有符合要求的冰鞋!\n");
}
else
{
// 位置错误
printf("\n\a未知错误!\n");
return;
}
// 询问是否继续
fflush(stdin);
printf("\n您还需要继续租用其它冰鞋吗? (Y/N): ");
StringInput(&input_option);
if(strcmp(StringGetString(&input_option), "Y") != 0 &&
strcmp(StringGetString(&input_option), "y") != 0 &&
strcmp(StringGetString(&input_option), "N") != 0 &&
strcmp(StringGetString(&input_option), "n") != 0)
{
printf("\n\n\a输入错误!\n");
flag_rent_continue = 0;
}
else if(!strcmp(StringGetString(&input_option), "N") ||
!strcmp(StringGetString(&input_option), "n"))
{
flag_rent_continue = 0;
}
} // end of while
}
// 冰鞋归还
void BackShoes()
{
SkateShoe ss; // 冰鞋信息对象
RentDetails rd; // 租用信息对象
BackDetails bd; // 归还信息对象
int pos_ss; // 相应的冰鞋信息记录在文件中的下标
int pos_rd; // 相应的租用信息记录在文件中的下标
int flag_back_continue = 1; // 标记 为 1 表示仍要归还其他冰鞋
String input_option; // 用户输入的选项
short flag_query_rent = 0; // 标记 为 1 表明有相应的租用记录
String input_user_name; // 用户输入的姓名
String input_id_number; // 用户输入的身份证号
String input_key_number; // 用户输入的冰鞋编号
Time input_back_time; // 用户输入的归还时间
// 常量 String 对象
String null;
StringCopyFromCharArray(&null, "null");
// 初始化各对象
SkateShoeInit(&ss);
RentDetailsInit(&rd);
StringInit(&input_user_name);
StringInit(&input_id_number);
StringInit(&input_key_number);
StringInit(&input_option);
while(flag_back_continue)
{
// 输入姓名
printf("\n请输入您的姓名: ");
StringInput(&input_user_name);
if(StringLength(input_user_name) == 0)
{
printf("\n\a输入有误!\n");
return;
}
// 输入身份证号
printf("您的身份证号: ");
StringInput(&input_id_number);
if(StringLength(input_id_number) == 0)
{
printf("\n\a输入有误!\n");
return;
}
// 输出用户租用记录
DisplayQueryTitle();
if((flag_query_rent = QueryRentDetailsFromFile(input_user_name, input_id_number, null, null)) == 1)
{
// 存在该用户的租用记录
// 输入归还的冰鞋编号
printf("请输入冰鞋编号: ");
StringInput(&input_key_number);
if(StringLength(input_key_number) == 0)
{
printf("\n\a输入错误!\n");
return;
}
// 取到对应的冰鞋记录
if((pos_ss = FindShoesByKey(input_key_number, &ss)) >= 0)
{
// 取到对应的租用记录
if((pos_rd = FindRentRecord(input_user_name, input_id_number, input_key_number, &rd)) >= 0)
{
// 输入冰鞋的归还时间
printf("时间,格式 时-分: ");
TimeInput(&input_back_time);
// 拼装新的 BackDetails 记录
bd.back_date = rd.date;
if((bd.lend_hours = CalculateHours(rd.rent_time, input_back_time)) == -1)
{
printf("\n\a请核对时间!\n");
return;
}
bd.rent_price_per_hour = rd.rent_price_per_hour;
bd.shoe_size = rd.shoe_size;
bd.shoe_type = rd.shoe_type;
bd.total_cost = bd.rent_price_per_hour * bd.lend_hours;
// 更新取到的 RentDetails 记录
rd.status = 0;
// 更新取到的 SkateShoe 记录
ss.rent_status = 0;
// 更新对应的 ShoeNumber 记录
UpdateNumberWhenBackShoes(ss);
// 将更新后的记录分别写入文件
if(!ShoesWrite2File(ss, pos_ss, 0) &&
!RentDetailsWrite2File(rd, pos_rd, 0) &&
!BackDetailsWrite2File(bd, 0, 1))
{
printf("\n冰鞋归还成功!\n");
// 输出计费单据
DisplayCostDetails(bd);
}
else
{
// 未知错误
printf("\n\a未知错误!\n");
return;
}
}
else if(pos_rd == -3)
{
// 没有相应的租用记录
printf("\n\a没有相应的租用记录!\n");
}
else
{
// 位置错误
printf("\n\a未知错误!\n");
return;
}
}
else if(pos_ss == -3)
{
// 没有此编号的冰鞋
printf("\n\a没有此编号的冰鞋!\n");
}
else
{
// 未知错误
printf("\n\a未知错误!\n");
return;
}
}
else if(flag_query_rent == 0)
{
// 没有相应的租用记录
printf("\a没有相应的租用记录!\n");
}
else
{
// 未知错误
printf("\a未知错误!\n");
return;
}
// 询问是否继续
fflush(stdin);
printf("\n您还需要归还其它冰鞋吗? (Y/N): ");
StringInput(&input_option);
if(strcmp(StringGetString(&input_option), "Y") != 0 &&
strcmp(StringGetString(&input_option), "y") != 0 &&
strcmp(StringGetString(&input_option), "N") != 0 &&
strcmp(StringGetString(&input_option), "n") != 0)
{
printf("\n\n\a输入错误!\n");
flag_back_continue = 0;
}
else if(!strcmp(StringGetString(&input_option), "N") ||
!strcmp(StringGetString(&input_option), "n"))
{
flag_back_continue = 0;
}
} // end of while
}
// 数据维护
void DataModify()
{
// 显示子系统菜单
ShowDataModifyMenu();
}
// 密码修改
void PasswordModify()
{
String new_pwd, confirm_pwd; // 新密码和第二次输入的新密码
short pwd_check; // 输入的旧密码是否验证通过
// 初始化各对象
StringInit(&new_pwd);
StringInit(&confirm_pwd);
// 验证密码
if((pwd_check = CheckPassword()) == 1)
{
// 验证通过
printf("\n\n请输入新密码,以 Enter 结束输入: ");
InputPassword(&new_pwd);
printf("\n\n请再输入新密码,以 Enter 结束输入: ");
InputPassword(&confirm_pwd);
// 验证两次输入的新密码是否一致
if(StringCompare(new_pwd, confirm_pwd) == 0)
{
// 一致
// 更新密码
if(UpdatePassword(new_pwd) == 0)
{
// 更新成功
printf("\n\n密码修改成功!\n");
}
else
{
// 未知错误
printf("\n\n\a未知错误!\n");
return;
}
}
else
{
// 不一致
printf("\n\n\a两次输入的密码不一致!\n");
return;
}
}
else if(pwd_check == 0)
{
// 验证失败
printf("\n\n\a密码错误!\n");
}
else if(pwd_check == 2)
{
// 初始化密码
printf("\n");
}
else
{
// 未知错误
printf("\n\n\a未知错误!\n");
}
}
// 综合查询
void GeneralQuery()
{
// 显示子系统菜单
ShowGeneralQueryMenu();
}
// 退出主系统
void QuitMainSystem()
{
printf("\n");
printf("-------------------------------------------------------------------------------\n");
printf("| 感 谢 使 用 冰 鞋 租 用 管 理 系 统 |\n");
printf("-------------------------------------------------------------------------------\n");
}
/******************** 数 据 维 护 子 系 统 函 数 实 现 ***********************/
// 新增冰鞋数据
void AddShoes()
{
SkateShoe ss; // 冰鞋信息对象
SkateShoeInit(&ss); // 初始化对象
// 获得用户输入
printf("\n");
if(GetShoeData(&ss, 0) == 0)
{
// 用户输入成功
// 将记录写入文件
if(ShoesWrite2File(ss, 0, 1) == 0)
{
// 写入成功
printf("\n新增数据成功!\n");
// 打印标签
DisplayLabel(ss);
// 更新 number.dat
UpdateNumberWhenAddShoes(ss, 0);
}
else
{
// 未知错误
printf("\n\a错误!\n");
}
}
else
{
// 用户输入出错
printf("\n\a输入出错,新增数据失败!\n");
}
}
// 更新冰鞋数据
void UpdateShoes()
{
int pos; // 相应的冰鞋信息记录在文件中的下标
SkateShoe old_ss; // 原冰鞋信息记录
SkateShoe new_ss; // 更新后的冰鞋信息记录
String input_key_number; // 输入的冰鞋编号
// 初始化各对象
SkateShoeInit(&old_ss);
SkateShoeInit(&new_ss);
StringInit(&input_key_number);
// 输入冰鞋编号
printf("\n请输入冰鞋编号: ");
StringInput(&input_key_number);
// 查询
if((pos = FindShoesByKey(input_key_number, &old_ss)) >= 0)
{
// 查询成功
if(old_ss.rent_status == 1)
{
// 如果冰鞋被借出则不允许更新信息
printf("\n\a冰鞋已被租用,不能更新该条记录!\n");
return;
}
else
{
// 可以更新这条记录
// 获得用户输入
if(GetShoeData(&new_ss, 1) == 0)
{
// 输入成功
StringCopy(&(new_ss.key_number), old_ss.key_number);
// 将新记录写入文件
if(ShoesWrite2File(new_ss, pos, 0) == 0)
{
// 更新成功
printf("\n更新成功!\n");
// 更新 number.dat
UpdateNumberWhenUpdateShoes(old_ss, new_ss);
}
else
{
// 未知错误
printf("\n\a错误,更新失败!\n");
return;
}
}
else
{
// 输入出错
printf("\n\a错误!\n");
return;
}
}
}
else if(pos == -3)
{
// 查询失败
printf("\n\a无此编号的冰鞋!\n");
}
else
{
// 未知错误
printf("\n\a未知错误!\n");
}
}
// 删除冰鞋数据
void DeleteShoes()
{
int pos; // 相应的冰鞋信息记录在文件中的下标
SkateShoe ss; // 冰鞋信息对象
String input_key_number; // 用户输入的冰鞋编号
// 初始化各对象
SkateShoeInit(&ss);
StringInit(&input_key_number);
// 输入冰鞋编号
printf("\n请输入冰鞋编号: ");
StringInput(&input_key_number);
// 查询
if((pos = FindShoesByKey(input_key_number, &ss)) >= 0)
{
// 查询成功
if(ss.rent_status == 1)
{
// 如果冰鞋借出则不能删除记录
printf("\n\a冰鞋已被租用,不能删除该条记录!\n");
return;
}
else
{
// 可以删除这条记录
ss.status = 0;
// 更新文件
if(ShoesWrite2File(ss, pos, 0) == 0)
{
// 删除成功
printf("\n删除成功!\n");
// 更新 number.dat
UpdateNumberWhenDeleteShoes(ss, 0);
}
else
{
// 未知错误
printf("\n\a错误,删除失败!\n");
return;
}
}
}
else if(pos == -3)
{
// 查询失败
printf("\n\a无此编号的冰鞋!\n");
}
else
{
// 未知错误
printf("\n\a未知错误!\n");
}
}
// 退出数据维护子系统
void QuitDataModifySystem()
{
printf("\n");
printf("-------------------------------------------------------------------------------\n");
printf("| 感 谢 使 用 数 据 维 护 子 系 统 |\n");
printf("-------------------------------------------------------------------------------\n");
}
/******************** 综 合 查 询 子 系 统 函 数 实 现 ***********************/
// 打印全部信息
void DisplayAllFiles()
{
printf("\n");
DisplayShoes(); // 打印 shoes.dat
DisplayNumber(); // 打印 number.dat
DisplayRent(); // 打印 rent.dat
DisplayCount(); // 打印 count.dat
}
// 查询统计
void Query()
{
// 显示子系统菜单
ShowQueryMenu();
}
// 退出综合查询子系统
void QuitGeneralQuerySystem()
{
printf("\n");
printf("-------------------------------------------------------------------------------\n");
printf("| 感 谢 使 用 综 合 查 询 子 系 统 |\n");
printf("-------------------------------------------------------------------------------\n");
}
/********************** 冰 鞋 租 还 处 理 函 数 实 现 ************************/
// 将记录 rd 写入文件 rent.dat
// append = 1 则追加写入 否则在下标 pos 指示的相对位置写入 程序返回
// 0 写入成功
// -1 打开文件错误
// -2 未知错误
short RentDetailsWrite2File(RentDetails rd, int pos, short append)
{
FILE *fp = fopen("rent.dat", "rb+");
if(fp == NULL)
{
printf("\n\a文件打开错误!\n");
return -1;
}
// 移动文件指针
if(append == 0)
{
rewind(fp);
fseek(fp, pos * sizeof(RentDetails), SEEK_SET);
}
else
{
fseek(fp, 0, SEEK_END);
}
// 将记录写入文件
if(fwrite(&rd, sizeof(RentDetails), 1, fp) == 1)
{
printf("\n数据写入成功!\n");
fclose(fp);
return 0;
}
else
{
printf("\n\a数据写入失败!\n");
fclose(fp);
return -2;
}
}
// 将记录 bd 写入文件 count.dat
// append = 1 则追加写入 否则在下标 pos 指示的相对位置写入 程序返回
// 0 写入成功
// -1 打开文件错误
// -2 未知错误
short BackDetailsWrite2File(BackDetails bd, int pos, short append)
{
FILE *fp = fopen("count.dat", "rb+");
if(fp == NULL)
{
printf("\n\a文件打开错误!\n");
return -1;
}
// 移动文件指针
if(append == 0)
{
rewind(fp);
fseek(fp, pos * sizeof(BackDetails), SEEK_SET);
}
else
{
fseek(fp, 0, SEEK_END);
}
// 将记录写入文件
if(fwrite(&bd, sizeof(BackDetails), 1, fp) == 1)
{
printf("\n数据写入成功!\n");
fclose(fp);
return 0;
}
else
{
printf("\n\a数据写入失败!\n");
fclose(fp);
return -2;
}
}
// 根据用户姓名 user_name 身份证号 id_number 冰鞋编号 key_number
// 在文件 rent.dat 中查找相应记录 程序返回
// >= 0 记录在文件中的下标
// -3 查找不成功
// -1 文件打开错误
// -2 未知错误
int FindRentRecord(String user_name, String id_number, String key_number, RentDetails *rd)
{
int pos = 0; // 对应记录在文件中的下标
FILE *fp = fopen("rent.dat", "rb");
if(fp == NULL)
{
printf("\n\a文件打开错误!\n");
return -1;
}
// 初始化对象
RentDetailsInit(rd);
// 遍历文件查询
while(!feof(fp))
{
if(fread(rd, sizeof(RentDetails), 1, fp) == 1)
{
if(rd->status == 1 &&
!StringCompare(rd->user_name, user_name) &&
!StringCompare(rd->id_number, id_number) &&
!StringCompare(rd->shoe_key_number, key_number))
{
// 查找成功
fclose(fp);
return pos;
}
++pos;
}
}
// 查找失败
fclose(fp);
RentDetailsInit(rd);
return -3;
}
/******************** 查 询 统 计 子 系 统 函 数 实 现 ***********************/
// 查询冰鞋信息
void QueryShoes()
{
// 存放用户输入
String input_key_number;
String input_type;
String input_size;
String input_color;
String input_brand;
String input_manufacturer;
String input_rent_status;
String input_remark;
// 初始化各对象
StringInit(&input_key_number);
StringInit(&input_type);
StringInit(&input_size);
StringInit(&input_color);
StringInit(&input_brand);
StringInit(&input_manufacturer);
StringInit(&input_rent_status);
StringInit(&input_remark);
// 输入查询条件
printf("\n请输入查询条件,不需要限制的字段请输入 null\n\n");
printf("冰鞋编码: ");
StringInput(&input_key_number);
printf("冰鞋类型,0 -> 速滑冰鞋 1 -> 花样冰鞋: ");
StringInput(&input_type);
if(strcmp(StringGetString(&input_type), "null") != 0 &&
strcmp(StringGetString(&input_type), "0") != 0 &&
strcmp(StringGetString(&input_type), "1") != 0)
{
printf("\n\a输入有误!\n");
return;
}
printf("鞋号: ");
StringInput(&input_size);
printf("冰鞋颜色: ");
StringInput(&input_color);
printf("冰鞋品牌: ");
StringInput(&input_brand);
printf("冰鞋厂家: ");
StringInput(&input_manufacturer);
printf("是否已租用,0 -> 未租用 1 -> 已租用: ");
StringInput(&input_rent_status);
if(strcmp(StringGetString(&input_rent_status), "null") != 0 &&
strcmp(StringGetString(&input_rent_status), "0") != 0 &&
strcmp(StringGetString(&input_rent_status), "1") != 0)
{
printf("\n\a输入有误!\n");
return;
}
printf("是否需要修理,0 -> 不需要 1-> 需要: ");
StringInput(&input_remark);
if(strcmp(StringGetString(&input_remark), "null") != 0 &&
strcmp(StringGetString(&input_remark), "0") != 0 &&
strcmp(StringGetString(&input_remark), "1") != 0)
{
printf("\n\a输入有误!\n");
return;
}
// 输入结束
// 查询并打印结果
DisplayQueryTitle();
QueryShoesFromFile(input_key_number, input_type, input_size,
input_color, input_brand, input_manufacturer,
input_rent_status, input_remark);
}
// 根据查询条件从文件 shoe.dat 中查询符合条件的记录 程序返回
// 0 没有符合条件的记录
// 1 有符合条件的记录
// -1 文件打开错误
short QueryShoesFromFile(String key_number, String type, String size,
String color, String brand, String manufacturer,
String rent_status, String remark)
{
SkateShoe ss; // 冰鞋信息对象
short flag_print = 0; // 标记是否打印了记录 1 表示打印过
FILE *fp = fopen("shoes.dat", "rb");
if(fp == NULL)
{
printf("\n\a文件打开错误!\n");
return -1;
}
// 初始化对象
SkateShoeInit(&ss);
// 遍历文件
printf("| %-7s%-10s%-7s%-7s%-9s%-10s%-9s%-8s%-8s|\n",
"编码", "类型", "鞋号", "颜色", "品牌", "单价", "厂家", "被租用", "需维修");
printf("-------------------------------------------------------------------------------\n");
while(!feof(fp))
{
if(fread(&ss, sizeof(SkateShoe), 1, fp) == 1 && ss.status == 1)
{
// 检查是否符合查询条件
if(
(!strcmp(StringGetString(&key_number), "null") || !StringCompare(key_number, ss.key_number))
&& (!strcmp(StringGetString(&type), "null") || atoi(StringGetString(&type)) == ss.type)
&& (!strcmp(StringGetString(&size), "null") || atof(StringGetString(&size)) == ss.size)
&& (!strcmp(StringGetString(&color), "null") || !StringCompare(color, ss.color))
&& (!strcmp(StringGetString(&brand), "null") || !StringCompare(brand, ss.brand))
&& (!strcmp(StringGetString(&manufacturer), "null") || !StringCompare(manufacturer, ss.manufacturer))
&& (!strcmp(StringGetString(&rent_status), "null") || atoi(StringGetString(&rent_status)) == ss.rent_status)
&& (!strcmp(StringGetString(&remark), "null") || atoi(StringGetString(&remark)) == ss.remark)
)
{
// 符合查询条件
printf("| %-7s%-10s%-7.1lf",
StringGetString(&ss.key_number),
(ss.type == 0? "速滑冰鞋": "花样冰鞋"),
ss.size);
printf("%-7s", StringGetString(&ss.color));
printf("%-9s", StringGetString(&ss.brand));
printf("%-10.2lf", ss.unit_price);
printf("%-9s%-8s%-8s|\n",
StringGetString(&ss.manufacturer),
(ss.rent_status == 0? "否": "是"),
(ss.remark == 0? "否": "是"));
flag_print = 1;
}
}
}
if(flag_print == 0)
{
printf("| 没 有 符 合 条 件 的 记 录 |\n");
}
printf("-------------------------------------------------------------------------------\n");
printf("\n\n");
fclose(fp);
return flag_print;
}
// 查询数量信息
void QueryNumber()
{
// 存放用户输入
String input_shoe_size;
String input_shoe_type;
String input_total_quantity;
String input_left_quantity;
// 初始化各对象
StringInit(&input_shoe_size);
StringInit(&input_shoe_type);
StringInit(&input_total_quantity);
StringInit(&input_left_quantity);
// 输入查询条件
printf("\n请输入查询条件,不需要限制的字段请输入 null\n\n");
printf("鞋号: ");
StringInput(&input_shoe_size);
if(StringLength(input_shoe_size) == 0)
{
printf("\n\a输入有误!\n");
return;
}
printf("冰鞋类型,0 -> 速滑冰鞋 1 -> 花样冰鞋: ");
StringInput(&input_shoe_type);
if(strcmp(StringGetString(&input_shoe_type), "null") != 0 &&
strcmp(StringGetString(&input_shoe_type), "0") != 0 &&
strcmp(StringGetString(&input_shoe_type), "1") != 0)
{
printf("\n\a输入有误!\n");
return;
}
printf("冰鞋总数量: ");
StringInput(&input_total_quantity);
printf("剩余量: ");
StringInput(&input_left_quantity);
// 输入结束
// 查询并打印结果
DisplayQueryTitle();
QueryNumberFromFile(input_shoe_size, input_shoe_type, input_total_quantity, input_left_quantity);
}
// 根据查询条件从文件 number.dat 中查询符合条件的记录 程序返回
// 0 没有符合条件的记录
// 1 有符合条件的记录
// -1 文件打开错误
short QueryNumberFromFile(String shoe_size, String shoe_type, String total_quantity, String left_quantity)
{
ShoeNumber sn; // 冰鞋数量对象
short flag_print = 0; // 标记是否打印过记录 1 表示打印过
FILE *fp = fopen("number.dat", "rb");
if(fp == NULL)
{
printf("\n\a文件打开错误!\n");
return -1;
}
// 初始化对象
ShoeNumberInit(&sn);
// 遍历文件
printf("| %-20s%-20s%-20s%-12s|\n", "鞋号", "类型", "总数量", "剩余量");
printf("-------------------------------------------------------------------------------\n");
while(!feof(fp))
{
if(fread(&sn, sizeof(ShoeNumber), 1, fp) == 1 && sn.status == 1)
{
// 检查是否符合查询条件
if(
(!strcmp(StringGetString(&shoe_size), "null") || atof(StringGetString(&shoe_size)) == sn.shoe_size)
&& (!strcmp(StringGetString(&shoe_type), "null") || atoi(StringGetString(&shoe_type)) == sn.shoe_type)
&& (!strcmp(StringGetString(&total_quantity), "null") || atoi(StringGetString(&total_quantity)) == sn.total_quantity)
&& (!strcmp(StringGetString(&left_quantity), "null") || atoi(StringGetString(&left_quantity)) == sn.left_quantity)
)
{
// 符合查询条件
printf("| %-20.1lf%-20s%-20d%-12d|\n",
sn.shoe_size,
(sn.shoe_type == 0? "速滑冰鞋": "花样冰鞋"),
sn.total_quantity, sn.left_quantity);
flag_print = 1;
}
}
}
if(flag_print == 0)
{
printf("| 没 有 符 合 条 件 的 记 录 |\n");
}
printf("-------------------------------------------------------------------------------\n");
printf("\n\n");
fclose(fp);
return flag_print;
}
// 查询租用信息
void QueryRentDetails()
{
// 存放用户输入
String input_user_name;
String input_id_number;
String input_shoe_size;
String input_date;
// 初始化各对象
StringInit(&input_user_name);
StringInit(&input_id_number);
StringInit(&input_shoe_size);
StringInit(&input_date);
// 输入查询条件
printf("\n请输入查询条件,不需要限制的字段请输入 null\n\n");
printf("用户姓名: ");
StringInput(&input_user_name);
if(StringLength(input_user_name) == 0)
{
printf("\n\a输入有误!\n");
return;
}
printf("身份证号: ");
StringInput(&input_id_number);
if(StringLength(input_id_number) == 0)
{
printf("\n\a输入有误!\n");
return;
}
printf("鞋号: ");
StringInput(&input_shoe_size);
printf("租用日期: ");
StringInput(&input_date);
// 输入结束
// 查询并打印结果
DisplayQueryTitle();
QueryRentDetailsFromFile(input_user_name, input_id_number, input_shoe_size, input_date);
}
// 根据查询条件从文件 rent.dat 中查询符合条件的记录 程序返回
// 0 没有符合条件的记录
// 1 有符合条件的记录
// -1 文件打开错误
short QueryRentDetailsFromFile(String user_name, String id_number, String size, String date)
{
RentDetails rd; // 租用记录对象
short flag_print = 0; // 标记是否打印过记录 1 为打印过
FILE *fp = fopen("rent.dat", "rb");
if(fp == NULL)
{
printf("\n\a文件打开错误!\n");
return -1;
}
// 初始化对象
RentDetailsInit(&rd);
// 遍历文件
printf("| %-7s%-10s%-10s%-7s%-7s%-10s%-9s%-7s%-8s|\n",
"姓名", "身份证号", "联系方式", "鞋号", "编码", "类型", "日期", "时间", "租金/时");
printf("-------------------------------------------------------------------------------\n");
while(!feof(fp))
{
if(fread(&rd, sizeof(RentDetails), 1, fp) == 1 && rd.status == 1)
{
// 检查是否符合查询条件
if(
(!strcmp(StringGetString(&user_name), "null") || !StringCompare(user_name, rd.user_name))
&& (!strcmp(StringGetString(&id_number), "null") || !StringCompare(id_number, rd.id_number))
&& (!strcmp(StringGetString(&size), "null") || atof(StringGetString(&size)) == rd.shoe_size)
&& (!strcmp(StringGetString(&date), "null") || !strcmp(StringGetString(&date), DateGetString(rd.date)))
)
{
// 符合查询条件
printf("| %-7s", StringGetString(&rd.user_name));
printf("%-10s", StringGetString(&rd.id_number));
printf("%-10s", StringGetString(&rd.contact_info));
printf("%-7.1lf", rd.shoe_size);
printf("%-7s%-10s", StringGetString(&rd.shoe_key_number),
(rd.shoe_type == 0? "速滑冰鞋": "花样冰鞋"));
printf("%-9s", DateGetString(rd.date));
printf("%-7s", TimeGetString(rd.rent_time));
printf("%-8.2lf|\n", rd.rent_price_per_hour);
flag_print = 1;
}
}
}
if(flag_print == 0)
{
printf("| 没 有 符 合 条 件 的 记 录 |\n");
}
printf("-------------------------------------------------------------------------------\n");
printf("\n\n");
fclose(fp);
return flag_print;
}
// 计算当日收入
void CalculateIncome()
{
String input_date; // 用户输入的日期
BackDetails bd; // 归还记录对象
short flag_print = 0; // 标记是否打印过记录 1 为打印过
double shoe_size[100]; // 存放统计的鞋号
double income[100]; // 存放对应鞋号的收入
int record_cnt = 0; // 统计后记录的条数
int i; // 循环变量
FILE *fp = fopen("count.dat", "rb");
if(fp == NULL)
{
printf("\n\a文件打开错误!\n");
return;
}
// 初始化对象
StringInit(&input_date);
// 输入要统计的日期
printf("\n请输入日期,格式 年/月/日: ");
StringInput(&input_date);
if(StringLength(input_date) == 0)
{
printf("\n\a输入有误!\n");
fclose(fp);
return;
}
// 遍历文件
while(!feof(fp))
{
// 检测记录的日期是否跟输入的日期一致
if(fread(&bd, sizeof(BackDetails), 1, fp) == 1 &&
!strcmp(StringGetString(&input_date), DateGetString(bd.back_date)))
{
// 查找 bd 记录中的鞋号是否已经出现
for(i = 0; i < record_cnt; ++i)
{
if(bd.shoe_size == shoe_size[i])
{
break;
}
}
if(i < record_cnt)
{
// 已存在的鞋号
income[i] += bd.total_cost;
}
else
{
// 未出现的鞋号
shoe_size[record_cnt] = bd.shoe_size;
income[record_cnt] = bd.total_cost;
++record_cnt;
}
}
}
fclose(fp);
// 展示结果
DisplayStatisticsTitle();
printf("| %-20s%-22s |\n", "鞋号", "对应总收入");
printf("|-----------------------------------------------------------------------------|\n");
for(i = 0; i < record_cnt; ++i)
{
printf("| %-20.1lf%-22.2lf |\n", shoe_size[i], income[i]);
flag_print = 1;
}
if(flag_print == 0)
{
printf("| 没 有 符 合 条 件 的 记 录 |\n");
}
printf("-------------------------------------------------------------------------------\n");
printf("\n\n");
}
// 退出查询统计子系统
void QuitQuerySystem()
{
printf("\n");
printf("-------------------------------------------------------------------------------\n");
printf("| 感 谢 使 用 查 询 统 计 子 系 统 |\n");
printf("-------------------------------------------------------------------------------\n");
}
// 显示查询结果列表表头
void DisplayQueryTitle()
{
printf("\n");
printf("-------------------------------------------------------------------------------\n");
printf("| 查 询 结 果 列 表 |\n");
printf("-------------------------------------------------------------------------------\n");
}
// 同时统计结果列表表头
void DisplayStatisticsTitle()
{
printf("\n");
printf("-------------------------------------------------------------------------------\n");
printf("| 统 计 结 果 列 表 |\n");
printf("-------------------------------------------------------------------------------\n");
}
/**************************** 打 印 函 数 实 现 ******************************/
// 打印 shoes.dat 程序返回
// 0 没有符合条件的记录
// 1 有符合条件的记录
// -1 文件打开错误
short DisplayShoes()
{
short flag_print = 0; // 打印标记 为 1 表示打印过
SkateShoe ss; // 冰鞋信息对象
FILE *fp = fopen("shoes.dat", "rb");
if(fp == NULL)
{
printf("\a打开文件错误!\n");
return -1;
}
// 初始化对象
SkateShoeInit(&ss);
// 遍历文件 打印记录
printf("-------------------------------------------------------------------------------\n");
printf("| s h o e s . d a t |\n");
printf("-------------------------------------------------------------------------------\n");
printf("| %-7s%-10s%-7s%-7s%-9s%-10s%-9s%-8s%-8s|\n",
"编码", "类型", "鞋号", "颜色", "品牌", "单价", "厂家", "被租用", "需维修");
printf("-------------------------------------------------------------------------------\n");
while(!feof(fp))
{
if(fread(&ss, sizeof(SkateShoe), 1, fp) == 1 && ss.status == 1)
{
printf("| %-7s%-10s%-7.1lf",
StringGetString(&ss.key_number),
(ss.type == 0? "速滑冰鞋": "花样冰鞋"),
ss.size);
printf("%-7s", StringGetString(&ss.color));
printf("%-9s", StringGetString(&ss.brand));
printf("%-10.2lf", ss.unit_price);
printf("%-9s%-8s%-8s|\n",
StringGetString(&ss.manufacturer),
(ss.rent_status == 0? "否": "是"),
(ss.remark == 0? "否": "是"));
flag_print = 1;
}
}
if(flag_print == 0)
{
printf("| 没 有 数 据 |\n");
}
printf("-------------------------------------------------------------------------------\n");
printf("\n\n");
fclose(fp);
return flag_print;
}
// 打印 number.dat 程序返回
// 0 没有符合条件的记录
// 1 有符合条件的记录
// -1 文件打开错误
short DisplayNumber()
{
short flag_print = 0; // 打印标记 为 1 表明打印过
ShoeNumber sn; // 冰鞋数量信息对象
FILE *fp = fopen("number.dat", "rb");
if(fp == NULL)
{
printf("\a打开文件错误!\n");
return -1;
}
// 初始化对象
ShoeNumberInit(&sn);
// 遍历文件 打印记录
printf("-------------------------------------------------------------------------------\n");
printf("| n u m b e r . d a t |\n");
printf("-------------------------------------------------------------------------------\n");
printf("| %-20s%-20s%-20s%-12s|\n", "鞋号", "类型", "总数量", "剩余量");
printf("-------------------------------------------------------------------------------\n");
while(!feof(fp))
{
if(fread(&sn, sizeof(ShoeNumber), 1, fp) == 1 && sn.status == 1)
{
printf("| %-20.1lf%-20s%-20d%-12d|\n",
sn.shoe_size,
(sn.shoe_type == 0? "速滑冰鞋": "花样冰鞋"),
sn.total_quantity, sn.left_quantity);
flag_print = 1;
}
}
if(flag_print == 0)
{
printf("| 没 有 数 据 |\n");
}
printf("-------------------------------------------------------------------------------\n");
printf("\n\n");
fclose(fp);
return flag_print;
}
// 打印 rent.dat 程序返回
// 0 没有符合条件的记录
// 1 有符合条件的记录
// -1 文件打开错误
short DisplayRent()
{
short flag_print = 0; // 打印标记 为 1 表示打印过
RentDetails rd; // 租用信息对象
FILE *fp = fopen("rent.dat", "rb");
if(fp == NULL)
{
printf("\a打开文件错误!\n");
return -1;
}
// 初始化对象
RentDetailsInit(&rd);
// 遍历文件 打印记录
printf("-------------------------------------------------------------------------------\n");
printf("| r e n t . d a t |\n");
printf("-------------------------------------------------------------------------------\n");
printf("| %-7s%-10s%-10s%-7s%-7s%-10s%-9s%-7s%-8s|\n",
"姓名", "身份证号", "联系方式", "鞋号", "编码", "类型", "日期", "时间", "租金/时");
printf("-------------------------------------------------------------------------------\n");
while(!feof(fp))
{
if(fread(&rd, sizeof(RentDetails), 1, fp) == 1 && rd.status == 1)
{
printf("| %-7s", StringGetString(&rd.user_name));
printf("%-10s", StringGetString(&rd.id_number));
printf("%-10s", StringGetString(&rd.contact_info));
printf("%-7.1lf", rd.shoe_size);
printf("%-7s%-10s", StringGetString(&rd.shoe_key_number),
(rd.shoe_type == 0? "速滑冰鞋": "花样冰鞋"));
printf("%-9s", DateGetString(rd.date));
printf("%-7s", TimeGetString(rd.rent_time));
printf("%-8.2lf|\n", rd.rent_price_per_hour);
flag_print = 1;
}
}
if(flag_print == 0)
{
printf("| 没 有 数 据 |\n");
}
printf("-------------------------------------------------------------------------------\n");
printf("\n\n");
fclose(fp);
return flag_print;
}
// 打印 count.dat 程序返回
// 0 没有符合条件的记录
// 1 有符合条件的记录
// -1 文件打开错误
short DisplayCount()
{
short flag_print = 0; // 打印标记 为 1 表示打印过
BackDetails bd; // 归还信息对象
FILE *fp = fopen("count.dat", "rb");
if(fp == NULL)
{
printf("\a打开文件错误!\n");
return -1;
}
// 遍历文件 打印记录
printf("-------------------------------------------------------------------------------\n");
printf("| c o u n t . d a t |\n");
printf("-------------------------------------------------------------------------------\n");
printf("| %-12s%-9s%-13s%-16s%-12s%-12s |\n",
"日期", "鞋号", "类型", "使用时间/时", "租金/时", "总费用/元");
printf("-------------------------------------------------------------------------------\n");
while(!feof(fp))
{
if(fread(&bd, sizeof(BackDetails), 1, fp) == 1)
{
printf("| %-12s%-9.1lf%-13s%-16.1lf%-12.2lf%-12.2lf |\n",
DateGetString(bd.back_date),
bd.shoe_size,
(bd.shoe_type == 0? "速滑冰鞋": "花样冰鞋"),
bd.lend_hours,
bd.rent_price_per_hour,
bd.total_cost);
flag_print = 1;
}
}
if(flag_print == 0)
{
printf("| 没 有 数 据 |\n");
}
printf("-------------------------------------------------------------------------------\n");
printf("\n");
fclose(fp);
return flag_print;
}
// 打印计费单据
void DisplayCostDetails(BackDetails bd)
{
printf("\n-------------------------------------------------------------------------------\n");
printf("| 计 费 单 据 |\n");
printf("-------------------------------------------------------------------------------\n");
printf("| %-12s%-9s%-13s%-16s%-12s%-12s |\n",
"日期", "鞋号", "类型", "使用时间/时", "租金/时", "总费用/元");
printf("-------------------------------------------------------------------------------\n");
printf("| %-12s%-9.1lf%-13s%-16.1lf%-12.2lf%-12.2lf |\n",
DateGetString(bd.back_date),
bd.shoe_size,
(bd.shoe_type == 0? "速滑冰鞋": "花样冰鞋"),
bd.lend_hours,
bd.rent_price_per_hour,
bd.total_cost);
printf("-------------------------------------------------------------------------------\n\n");
}
/********************** 冰 鞋 数 据 处 理 函 数 实 现 ************************/
// 冰鞋详细信息对象初始化
void SkateShoeInit(SkateShoe *ss)
{
ss->status = 1;
}
// 冰鞋数量信息对象初始化
void ShoeNumberInit(ShoeNumber *sn)
{
sn->status = 1;
}
// 租用详细信息对象初始化
void RentDetailsInit(RentDetails *rd)
{
rd->deposit = 100; // 押金
rd->rent_price_per_hour = 30; // 每小时租费
rd->status = 1;
}
// 设置 SkateShoe 对象 *ss 的值
// UpdateShoes() 为 1 表示是在更新记录 此时不用输入编号
// 成功返回 0
// 失败返回 -1
short GetShoeData(SkateShoe *ss, short update)
{
String input_value; // 用户输入
// 初始化各对象
SkateShoeInit(ss);
StringInit(&input_value);
// 检测是否是 UpdateShoes() 调用
if(update == 0)
{
// 是 update 调用
// 不能更新冰鞋编号
printf("请输入冰鞋的编号: ");
StringInput(&input_value);
if(input_value.length == 0)
{
printf("\n\a输入有误!\n");
return -1;
}
StringCopy(&(ss->key_number), input_value);
}
else
{
printf("\n");
}
// 输入冰鞋类型
printf("请选择冰鞋的类型,0 -> 速滑冰鞋 1 -> 花样冰鞋: ");
StringInput(&input_value);
if(input_value.length != 1 ||
(strcmp(StringGetString(&input_value), "0") != 0 &&
strcmp(StringGetString(&input_value), "1") != 0))
{
printf("\n\a输入有误!\n");
return -1;
}
ss->type = atoi(StringGetString(&input_value));
// 鞋号
printf("请输入鞋号: ");
StringInput(&input_value);
if(input_value.length == 0)
{
printf("\n\a输入有误!\n");
return -1;
}
ss->size = atof(StringGetString(&input_value));
// 颜色
printf("请输入鞋的颜色: ");
StringInput(&input_value);
if(input_value.length == 0)
{
printf("\n\a输入有误!\n");
return -1;
}
StringCopy(&(ss->color), input_value);
// 品牌
printf("请输入鞋的品牌: ");
StringInput(&input_value);
if(input_value.length == 0)
{
printf("\n\a输入有误!\n");
return -1;
}
StringCopy(&(ss->brand), input_value);
// 单价
printf("请输入单价: ");
StringInput(&input_value);
if(input_value.length == 0)
{
printf("\n\a输入有误!\n");
return -1;
}
ss->unit_price = atof(StringGetString(&input_value));
// 厂家
printf("请输入厂家: ");
StringInput(&input_value);
if(input_value.length == 0)
{
printf("\n\a输入有误!\n");
return -1;
}
StringCopy(&(ss->manufacturer), input_value);
// 租用状态
printf("请选择冰鞋租用状态,0 -> 未租用 1 -> 已租用: ");
StringInput(&input_value);
if(input_value.length != 1 ||
(strcmp(StringGetString(&input_value), "0") != 0 &&
strcmp(StringGetString(&input_value), "1") != 0))
{
printf("\n\a输入有误!\n");
return -1;
}
ss->rent_status = atoi(StringGetString(&input_value));
// 是否需要维修 使用说明
printf("请选择冰鞋是否需要维修,0 -> 不需要 1 -> 需要: ");
StringInput(&input_value);
if(input_value.length != 1 ||
(strcmp(StringGetString(&input_value), "0") != 0 &&
strcmp(StringGetString(&input_value), "1") != 0))
{
printf("\n\a输入有误!\n");
return -1;
}
ss->remark = atoi(StringGetString(&input_value));
return 0;
}
// 将记录 ss 写入文件 shoes.dat
// append = 1 则追加写入 否则在下标 pos 指示的相对位置写入 返回
// 0 写入成功
// -1 打开文件错误
// -2 未知错误
short ShoesWrite2File(SkateShoe ss, long pos, short append)
{
FILE *fp = fopen("shoes.dat", "rb+");
if(fp == NULL)
{
printf("\n\a打开文件错误!\n");
return -1;
}
// 移动文件指针
if(append == 0)
{
rewind(fp); // 需要先让文件指针回到文件头 - -#
fseek(fp, pos * sizeof(SkateShoe), SEEK_SET);
}
else
{
fseek(fp, 0, SEEK_END);
}
// 将记录写入文件
if(fwrite(&ss, sizeof(SkateShoe), 1, fp) == 1)
{
printf("\n数据写入成功!\n");
fclose(fp);
return 0;
}
else
{
printf("\n数据写入失败!\n");
fclose(fp);
return -2;
}
}
// 通过编号 key 查找冰鞋信息
// >=0 查找成功 返回的是记录在文件中的下标
// -3 查找失败
// -1 文件打开错误
int FindShoesByKey(String key, SkateShoe *ss)
{
int pos = 0; // 相应冰鞋信息记录在文件中的下标
FILE *fp = fopen("shoes.dat", "rb");
if(fp == NULL)
{
printf("\n\a文件打开错误!\n");
return -1;
}
// 遍历文件
while(!feof(fp))
{
if(fread(ss, sizeof(SkateShoe), 1, fp) == 1)
{
// 检查是否符合查找条件
if(ss->status == 1 &&
StringCompare(ss->key_number, key) == 0)
{
// 查找成功
fclose(fp);
return pos;
}
++pos;
}
}
// 查找失败
fclose(fp);
SkateShoeInit(ss);
return -3;
}
// 新增冰鞋数据时显示生成的标签
void DisplayLabel(SkateShoe ss)
{
printf("\n-------------------------------------------------------------------------------\n");
printf("| 冰 鞋 标 签 |\n");
printf("-------------------------------------------------------------------------------\n");
printf("| %-20s%-24s%-16s |\n", "编码", "类型", "鞋号");
printf("-------------------------------------------------------------------------------\n");
printf("| %-20s%-24s%-16.1lf |\n",
StringGetString(&ss.key_number), (ss.type == 0? "速滑冰鞋": "花样冰鞋"), ss.size);
printf("-------------------------------------------------------------------------------\n\n");
}
/*********************** 冰 鞋 数 量 维 护 函 数 实 现 ***********************/
// 在新增冰鞋数据时更新数量文件 number.dat
// flag_back = 1 时表明是 UpdateNumberWhenBackShoes() 调用
void UpdateNumberWhenAddShoes(SkateShoe ss, short flag_back)
{
ShoeNumber sn; // 冰鞋数量对象
int pos; // 相应的冰鞋数量记录在文件中的下标
// 初始化对象
ShoeNumberInit(&sn);
// 取到数量记录
if((pos = FindNumberRecord(ss.size, ss.type, &sn)) >= 0)
{
// 更新已存在的 ShoeNumber 记录
// 处理记录的 total_quantity 和 left_quantity
if(flag_back == 0)
{
++sn.total_quantity;
sn.left_quantity += (ss.rent_status == 0? 1: 0);
}
else
{
++sn.left_quantity;
}
// 写入文件
if(NumberWrite2File(sn, pos, 0) == 0)
{
printf("\n冰鞋数量更新成功!\n");
return;
}
else
{
printf("\n\a未知错误!\n");
return;
}
}
else if(pos == -3)
{
// 新增一条 ShoeNumber 记录
sn.shoe_size = ss.size;
sn.shoe_type = ss.type;
sn.left_quantity = (ss.rent_status == 0? 1: 0);
sn.total_quantity = 1;
// 写入文件
if(NumberWrite2File(sn, 0, 1) == 0)
{
printf("\n冰鞋数量更新成功!\n");
return;
}
else
{
printf("\n\a未知错误!\n");
return;
}
}
else
{
// 未知错误
printf("\n\a未知错误!\n");
return;
}
}
// 在删除冰鞋数据时更新数量文件 number.dat
// flag_rent = 1 时表明是 UpdateNumberWhenRentShoes() 调用
void UpdateNumberWhenDeleteShoes(SkateShoe ss, short flag_rent)
{
ShoeNumber sn; // 冰鞋数量对象
int pos; // 数量记录在文件中的下标
// 初始化对象
ShoeNumberInit(&sn);
// 取到数量记录
if((pos = FindNumberRecord(ss.size, ss.type, &sn)) >= 0)
{
// 更新 ShoeNumber 记录
// 处理记录的 total_quantity 和 left_quantity
if(flag_rent == 0)
{
--sn.total_quantity;
--sn.left_quantity;
}
else
{
--sn.left_quantity;
}
// 写入文件
if(NumberWrite2File(sn, pos, 0) == 0)
{
printf("\n冰鞋数量更新成功!\n");
return;
}
else
{
printf("\n\a未知错误!\n");
return;
}
}
else
{
// 未知错误
printf("\n\a未知错误!\n");
return;
}
}
// 在更新冰鞋数据时更新数量文件 number.dat
void UpdateNumberWhenUpdateShoes(SkateShoe old_ss, SkateShoe new_ss)
{
if(old_ss.size == new_ss.size &&
old_ss.type == new_ss.type &&
old_ss.rent_status == new_ss.rent_status)
{
// 不需要更新 number.dat
return;
}
else
{
// 需要更新
UpdateNumberWhenDeleteShoes(old_ss, 0);
UpdateNumberWhenAddShoes(new_ss, 0);
}
}
// 在租用冰鞋时更新数量文件 number.dat
void UpdateNumberWhenRentShoes(SkateShoe ss)
{
UpdateNumberWhenDeleteShoes(ss, 1);
}
// 在退租冰鞋时更新数量文件 number.dat
void UpdateNumberWhenBackShoes(SkateShoe ss)
{
UpdateNumberWhenAddShoes(ss, 1);
}
// 向文件 number.dat 中写入一条记录
// append = 1 则追加写入
// 否则在下标 pos 指示的相对位置写入
// 0 写入成功
// -1 文件打开错误
// -2 未知错误
short NumberWrite2File(ShoeNumber sn, int pos, short append)
{
FILE *fp = fopen("number.dat", "r+");
if(fp == NULL)
{
printf("\n\a文件打开错误!\n");
return -1;
}
// 移动文件指针
if(append == 0)
{
rewind(fp);
fseek(fp, pos * sizeof(ShoeNumber), SEEK_SET);
}
else
{
fseek(fp, 0, SEEK_END);
}
// 写入文件
if(fwrite(&sn, sizeof(ShoeNumber), 1, fp) == 1)
{
printf("\n数据写入成功!\n");
fclose(fp);
return 0;
}
else
{
printf("\n数据写入失败!\n");
fclose(fp);
return -2;
}
}
// 根据鞋号和冰鞋类型在 number.dat 文件中找到记录的下标并返回
// >0 查找成功
// -3 查找失败
// -1 文件打开错误
int FindNumberRecord(double shoe_size, ShoeType st, ShoeNumber *sn)
{
int pos = 0; // 数量记录在文件中的下标
FILE *fp = fopen("number.dat", "rb");
if(fp == NULL)
{
printf("\n\a文件打开错误!\n");
return -1;
}
// 初始化对象
ShoeNumberInit(sn);
// 遍历文件
while(!feof(fp))
{
if(fread(sn, sizeof(ShoeNumber), 1, fp) == 1)
{
// 检查是否符合查找条件
if(sn->status == 1 &&
sn->shoe_size == shoe_size && sn->shoe_type == st)
{
// 查找成功
fclose(fp);
return pos;
}
++pos;
}
}
// 查找失败
fclose(fp);
ShoeNumberInit(sn);
return -3;
}
/************************** 密 码 处 理 函 数 实 现 **************************/
// 初始化密码为 gitzhou
void InitPassword()
{
String pwd; // 存放初始密码的 String 对象
// 初始化并赋值
StringInit(&pwd);
StringCopyFromCharArray(&pwd, "gitzhou");
// 更新密码
if(UpdatePassword(pwd) == 0)
{
// 更新成功
printf("\n\n密码初始化成功!");
}
else
{
// 更新失败
printf("\n\n\a未知错误!");
}
}
// 更新密码为 str 返回
// 0 更新成功
// -1 文件打开错误
// -2 未知错误
short UpdatePassword(String str)
{
FILE *fp = fopen("password.dat", "wb");
if(fp == NULL)
{
printf("\n\n\a打开文件错误!");
return -1;
}
// 将新密码写入文件
if(fwrite(&str, sizeof(String), 1, fp) == 1)
{
// 更新成功
printf("\n\n密码更新成功!");
fclose(fp);
return 0;
}
else
{
// 未知错误
printf("\n\n\a未知错误!");
fclose(fp);
return -2;
}
}
// 处理密码输入的同时在控制台上显示星号
void InputPassword(String *str)
{
char string[STRING_MAX_SIZE]; // 存放用户输入的字符
int string_len = 0; // 用户输入的字符个数
char ch; // 临时变量
// 读取输入 拼装字符串
while((ch = getchar()) != '\n')
{
//putchar('*');
string[string_len++] = ch;
}
string[string_len] = 0;
// 赋值
StringCopyFromCharArray(str, string);
}
// 检测用户输入的密码是否正确 返回
// 2 密码初始化成功
// 1 密码正确
// 0 密码错误
// -1 文件打开错误
// -2 未知错误
short CheckPassword()
{
String pwd; // 存放系统密码
String input_pwd; // 存放用户输入的密码
FILE *fp;
// 初始化各对象
StringInit(&pwd);
StringInit(&input_pwd);
if((fp = fopen("password.dat", "rb"))== NULL)
{
printf("\n\a打开文件错误!\n");
return -1;
}
// 让用户输入密码
printf("\n请输入密码,以 Enter 结束输入: ");
InputPassword(&input_pwd);
// 检测是否是初始化密码的输入
if(strcmp(StringGetString(&input_pwd), "!@#$%^&*()") == 0)
{
// 初始化密码
InitPassword();
fclose(fp);
return 2;
}
if(fread(&pwd, sizeof(String), 1, fp) == 1)
{
// 验证密码
if(StringCompare(input_pwd, pwd) == 0)
{
// 验证通过
fclose(fp);
return 1;
}
else
{
// 验证失败
fclose(fp);
return 0;
}
}
else
{
// 未知错误
fclose(fp);
return -2;
}
}
/**************************** 菜 单 函 数 实 现 ******************************/
// 显示程序主菜单
void ShowMainMenu()
{
String input_option; // 用户输入
int option; // 由用户输入转换成的选项值
StringInit(&input_option);
while(1)
{
printf("-------------------------------------------------------------------------------\n");
printf("| 欢 迎 使 用 冰 鞋 租 用 管 理 系 统 |\n");
printf("|-----------------------------------------------------------------------------|\n");
printf("| - 1 - 冰 鞋 租 用 |\n");
printf("| - 2 - 冰 鞋 归 还 |\n");
printf("| - 3 - 数 据 维 护 |\n");
printf("| - 4 - 密 码 修 改 |\n");
printf("| - 5 - 综 合 查 询 |\n");
printf("| - 6 - 退 出 系 统 |\n");
printf("-------------------------------------------------------------------------------\n");
fflush(stdin);
printf("请选择相应选项: ");
StringInput(&input_option);
// 转换
option = atoi(StringGetString(&input_option));
// 用户输入选项的错误检测
if(option != 1 && option != 2 && option != 3 &&
option != 4 && option != 5 && option != 6)
{
// 输入错误
printf("\n\a无此选项,请重新输入!\n\n");
continue;
}
// 输入无误
switch(option)
{
// 冰鞋租用
case 1:
RentShoes();
break;
// 冰鞋归还
case 2:
BackShoes();
break;
// 数据维护
case 3:
printf("\n");
DataModify();
break;
// 密码修改
case 4:
PasswordModify();
break;
// 综合查询
case 5:
printf("\n");
GeneralQuery();
break;
// 退出系统
case 6:
QuitMainSystem();
return;
// 未知错误
default:
printf("\n\a未知错误,程序结束!\n\n");
return;
}
printf("\n");
}
}
// 显示数据维护菜单
void ShowDataModifyMenu()
{
String input_option; // 用户输入
int option; // 由用户输入转换成的选项值
StringInit(&input_option);
while(1)
{
printf("-------------------------------------------------------------------------------\n");
printf("| 欢 迎 进 入 数 据 维 护 子 系 统 |\n");
printf("|-----------------------------------------------------------------------------|\n");
printf("| - 1 - 新 增 冰 鞋 数 据 |\n");
printf("| - 2 - 更 新 冰 鞋 数 据 |\n");
printf("| - 3 - 删 除 冰 鞋 数 据 |\n");
printf("| - 4 - 退 出 维 护 菜 单 |\n");
printf("-------------------------------------------------------------------------------\n");
fflush(stdin);
printf("请选择相应选项: ");
StringInput(&input_option);
// 转换
option = atoi(StringGetString(&input_option));
// 用户输入选项的错误检测
if(option != 1 && option != 2 && option != 3 && option != 4)
{
// 输入错误
printf("\n\a无此选项,请重新输入!\n\n");
continue;
}
// 输入无误
switch(option)
{
// 新增数据
case 1:
AddShoes();
break;
// 修改数据
case 2:
UpdateShoes();
break;
// 删除数据
case 3:
DeleteShoes();
break;
// 退出系统
case 4:
QuitDataModifySystem();
return;
// 未知错误
default:
printf("\n\a未知错误!\n\n");
return;
}
printf("\n");
}
}
// 显示综合查询菜单
void ShowGeneralQueryMenu()
{
String input_option; // 用户输入
int option; // 由用户输入转换成的选项值
StringInit(&input_option);
while(1)
{
printf("-------------------------------------------------------------------------------\n");
printf("| 欢 迎 进 入 综 合 查 询 子 系 统 |\n");
printf("|-----------------------------------------------------------------------------|\n");
printf("| - 1 - 输 出 全 部 信 息 |\n");
printf("| - 2 - 高 级 查 询 统 计 |\n");
printf("| - 3 - 退 出 查 询 菜 单 |\n");
printf("-------------------------------------------------------------------------------\n");
fflush(stdin);
printf("请选择相应选项: ");
StringInput(&input_option);
// 转换
option = atoi(StringGetString(&input_option));
// 用户输入选项的错误检测
if(option != 1 && option != 2 && option != 3)
{
// 输入错误
printf("\n\a无此选项,请重新输入!\n\n");
continue;
}
// 输入无误
switch(option)
{
// 输出全部信息
case 1:
DisplayAllFiles();
break;
// 查询统计
case 2:
Query();
break;
// 退出系统
case 3:
QuitGeneralQuerySystem();
return;
// 未知错误
default:
printf("\n\a未知错误!\n\n");
return;
}
printf("\n");
}
}
// 显示查询统计菜单
void ShowQueryMenu()
{
String input_option; // 用户输入
int option; // 由用户输入转换成的选项值
StringInit(&input_option);
while(1)
{
printf("-------------------------------------------------------------------------------\n");
printf("| 欢 迎 进 入 查 询 统 计 子 系 统 |\n");
printf("|-----------------------------------------------------------------------------|\n");
printf("| - 1 - 查 询 冰 鞋 信 息 |\n");
printf("| - 2 - 查 询 数 量 信 息 |\n");
printf("| - 3 - 查 询 租 用 信 息 |\n");
printf("| - 4 - 统 计 当 日 收 入 |\n");
printf("| - 5 - 退 出 查 询 菜 单 |\n");
printf("-------------------------------------------------------------------------------\n");
fflush(stdin);
printf("请选择相应选项: ");
StringInput(&input_option);
// 转换
option = atoi(StringGetString(&input_option));
// 用户输入选项的错误检测
if(option != 1 && option != 2 && option != 3 &&
option != 4 && option != 5)
{
// 输入错误
printf("\n\a无此选项,请重新输入!\n\n");
continue;
}
// 输入无误
switch(option)
{
// 查询冰鞋信息
case 1:
QueryShoes();
break;
// 查询数量信息
case 2:
QueryNumber();
break;
// 查询租用情况
case 3:
QueryRentDetails();
break;
// 计算当日收入
case 4:
CalculateIncome();
break;
// 退出系统
case 5:
QuitQuerySystem();
return;
// 未知错误
default:
printf("\n\a未知错误!\n\n");
return;
}
printf("\n");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment