停车场管理系统-详细讲解功能实现,附带源码

停车场管理系统 v1.0–详细讲解,附带源码

项目简介

这是一个功能完善的停车场管理系统,使用C语言开发,采用控制台交互界面。系统支持车辆进出管理、停车费用计算、车位管理、数据查询统计、数据持久化等完整功能。

主要特性

  • 车辆进出管理:记录车辆进入和离开,自动分配车位
  • 智能费用计算:根据停车时长自动计算费用,支持免费时长设置
  • 车位管理:自动分配和释放车位,实时显示空余车位
  • 数据查询:按车牌号查询、显示所有记录、统计信息
  • 配置管理:可配置总车位、每小时费用、免费时长等参数
  • 数据持久化:CSV格式存储,易于查看和编辑
  • 数据备份功能:自动备份,支持数据恢复
  • 友好的用户界面:彩色输出、清晰的菜单结构
  • 详细代码注释:所有函数都有详细的中文注释

运行界面

1. 主界面

在这里插入图片描述

2. 停车场管理界面

在这里插入图片描述

3. 数据查询界面

在这里插入图片描述

4. 系统设置界面

在这里插入图片描述
等等界面,内容完善!

快速开始

编译方法

Windows (MinGW)
gcc parking_manager.c -o parking_manager.exe
Linux/Mac
gcc parking_manager.c -o parking_manager

运行程序

Windows
parking_manager.exe
Linux/Mac
./parking_manager

功能详细说明

1. 停车场管理

1.1 车辆进入
  • 功能:记录车辆进入停车场
  • 输入项
    • 车牌号*(必填,不能重复进入)
    • 车辆类型(可选,如:小型车、大型车等)
  • 自动处理
    • 自动分配可用车位号
    • 记录进入时间(精确到秒)
    • 更新空余车位数量
  • 验证规则
    • 车牌号不能为空
    • 同一车牌号不能重复进入(如果车辆还在停车场内)
    • 停车场必须有空余车位
1.2 车辆离开
  • 功能:记录车辆离开停车场并计算费用
  • 输入项
    • 车牌号(必填)
  • 自动处理
    • 记录离开时间
    • 自动计算停车费用
    • 释放车位
    • 更新空余车位数量
  • 费用计算规则
    • 免费时长内不收费(默认15分钟)
    • 超过免费时长按小时计费(不足一小时按一小时计算)
    • 费用 = (停车时长 - 免费时长) / 60 * 每小时费用
1.3 查询停车场状态
  • 功能:显示停车场的实时状态信息
  • 显示内容
    • 总车位数量
    • 已停车位数量
    • 空余车位数量
    • 使用率(百分比)
    • 正在停车的车辆列表(车牌号、车辆类型、车位号、进入时间)

2. 数据查询

2.1 按车牌号查询
  • 功能:查询指定车牌号的停车记录
  • 显示内容
    • 车牌号
    • 车辆类型
    • 车位号
    • 进入时间
    • 离开时间(如果已离开)
    • 停车费用(如果已离开)
    • 当前状态(正在停车中或已离开)
    • 已停车时长(如果正在停车)
2.2 显示所有记录
  • 功能:以表格形式显示所有停车记录
  • 显示内容
    • 车牌号、车辆类型、车位号
    • 进入时间、离开时间
    • 停车费用
  • 说明:包括已完成和正在进行的停车记录
2.3 统计信息
  • 功能:显示停车场的统计信息
  • 统计内容
    • 今日统计
      • 今日进入车辆数量
      • 今日收入
    • 当前状态
      • 正在停车的车辆数量
      • 空余车位数量
    • 累计统计
      • 总收入
      • 总记录数

3. 系统设置

3.1 查看配置
  • 功能:显示当前停车场配置
  • 显示内容
    • 总车位数量
    • 每小时费用(元)
    • 免费时长(分钟)
3.2 修改配置
  • 功能:修改停车场配置参数
  • 可修改项
    • 总车位数量(1-1000)
    • 每小时费用(元,>=0)
    • 免费时长(分钟,>=0)
  • 说明:修改后自动保存到配置文件
3.3 保存数据
  • 功能:将当前内存中的数据保存到CSV文件
  • 默认文件parking_records.csv
  • 说明:建议在退出程序前保存数据
3.4 备份数据
  • 功能:创建数据备份文件
  • 备份位置backups/ 目录
  • 文件命名backup_YYYYMMDD_HHMMSS.csv
  • 说明
    • 备份文件包含时间戳,便于版本管理
    • 自动创建备份目录(如果不存在)
3.5 加载数据文件
  • 功能:从CSV文件加载停车记录数据
  • 操作:可以指定文件名,默认加载 parking_records.csv
  • 说明
    • 加载的数据会与现有数据合并
    • 自动更新空余车位数量
3.6 导出CSV文件
  • 功能:将数据导出到指定的CSV文件
  • 用途:数据迁移、数据分享、Excel分析
  • 格式:标准CSV格式,可用Excel打开

? 数据文件格式

CSV文件结构

系统使用CSV(逗号分隔值)格式存储停车记录,文件结构如下:

车牌号,车辆类型,车位号,进入时间,离开时间,费用
京A12345,小型车,1,2024-12-01 10:30:00,2024-12-01 12:45:00,15.00
京B67890,大型车,2,2024-12-01 11:00:00,未记录,0.00

字段说明

字段类型说明必填
车牌号字符串车辆牌照号码?
车辆类型字符串车辆类型(如:小型车、大型车)?
车位号整数分配的车位号(从1开始)?
进入时间时间字符串进入时间,格式:YYYY-MM-DD HH:MM:SS?
离开时间时间字符串离开时间,格式同上,未离开显示"未记录"?
费用浮点数停车费用(元),未离开为0.00?

配置文件格式

系统使用文本文件存储配置,文件名为 parking_config.txt

totalSpots=100
feePerHour=5.0
freeMinutes=15

数据导入注意事项

  1. 文件编码:建议使用UTF-8编码,避免中文乱码
  2. 表头:第一行必须是表头,系统会自动识别
  3. 字段顺序:必须按照上述顺序排列
  4. 时间格式:时间必须严格按照 YYYY-MM-DD HH:MM:SS 格式
  5. 数据验证
    • 车牌号不能为空
    • 车位号必须是正整数
    • 费用必须是数字

? 使用示例

示例1:车辆进入停车场

1. 选择"停车场管理" -> "车辆进入"
2. 输入车牌号:京A12345
3. 输入车辆类型:小型车(可选)
4. 系统自动分配车位号(如:1号车位)
5. 系统记录进入时间:2024-12-01 10:30:00
6. 显示进入成功信息

示例2:车辆离开停车场

1. 选择"停车场管理" -> "车辆离开"
2. 输入车牌号:京A12345
3. 系统自动计算:
   - 进入时间:2024-12-01 10:30:00
   - 离开时间:2024-12-01 12:45:00
   - 停车时长:2小时15分钟
   - 免费时长:15分钟
   - 计费时长:2小时
   - 停车费用:2 * 5.0 = 10.00 元
4. 释放车位,更新空余车位数量

示例3:查询停车场状态

1. 选择"停车场管理" -> "查询停车场状态"
2. 系统显示:
   - 总车位:100
   - 已停车位:25
   - 空余车位:75
   - 使用率:25.0%
   - 正在停车的车辆列表

示例4:修改配置

1. 选择"系统设置" -> "修改配置"
2. 输入总车位数量:150
3. 输入每小时费用:6.0
4. 输入免费时长:20
5. 系统保存配置到文件

技术实现

数据结构

// 停车记录结构体
typedef struct {
    char plate[PLATE_LEN];         // 车牌号
    char carType[CAR_TYPE_LEN];    // 车辆类型
    int spotNumber;                // 车位号
    time_t enterTime;              // 进入时间(时间戳)
    time_t exitTime;               // 离开时间(时间戳,0表示未离开)
    double fee;                    // 停车费用
    int isDeleted;                 // 删除标记
} ParkingRecord;

// 停车场配置结构体
typedef struct {
    int totalSpots;                // 总车位数量
    int freeSpots;                  // 当前空余车位
    double feePerHour;              // 每小时费用(元)
    int freeMinutes;                // 免费时长(分钟)
} ParkingConfig;

核心算法

  1. 车位分配算法

    • 使用线性查找,找到第一个空余车位
    • 时间复杂度:O(n),n为总车位数
    • 车位号从1开始连续分配
  2. 费用计算算法

    • 计算停车时长(秒转分钟)
    • 扣除免费时长
    • 按小时向上取整计费
    • 公式:费用 = ceil((时长 - 免费时长) / 60) * 每小时费用
  3. 数据存储

    • 使用静态数组存储,最大容量10000条记录
    • CSV格式持久化,便于查看和编辑
    • 支持软删除(isDeleted标记)
  4. 时间处理

    • 使用 time_t 类型存储时间戳
    • 使用 localtime() 转换为本地时间
    • 使用 strftime() 格式化时间显示

平台兼容性

  • Windows:完全支持,包含彩色输出和清屏功能
  • Linux/Mac:基本功能支持,部分UI功能可能受限

配置说明

可配置参数

在源代码中可以修改以下常量:

#define PLATE_LEN 20              // 车牌号最大长度
#define CAR_TYPE_LEN 20           // 车辆类型最大长度
#define MAX_PARKING_SPOTS 1000    // 最大停车位数量
#define MAX_RECORDS 10000         // 最大记录数量
#define DEFAULT_TOTAL_SPOTS 100   // 默认总车位
#define DEFAULT_FEE_PER_HOUR 5.0  // 默认每小时费用(元)
#define DEFAULT_FREE_MINUTES 15   // 默认免费时长(分钟)

费用计算规则

系统支持以下计费方式(可在代码中修改):

  1. 按小时计费(当前实现):

    • 免费时长内不收费
    • 超过免费时长按小时计费
    • 不足一小时按一小时计算
  2. 可扩展的计费方式

    • 可以修改 calculate_fee() 函数实现其他计费方式
    • 如:按分钟计费、分时段计费、会员折扣等

注意事项

数据安全

  1. 定期备份:建议定期使用备份功能保存数据
  2. 数据验证:系统会对输入数据进行基本验证,但仍需谨慎输入
  3. 文件权限:确保程序对数据文件有读写权限
  4. 文件编码:使用UTF-8编码,避免中文乱码

使用建议

  1. 首次使用:建议先配置停车场参数(总车位、费用等)
  2. 定期保存:修改数据后及时保存,避免数据丢失
  3. 备份策略:建议在重要操作前先备份数据
  4. 时间同步:确保系统时间准确,影响费用计算

已知限制

  1. 数据规模:最大支持10000条停车记录
  2. 车位数量:最大支持1000个车位
  3. 并发访问:不支持多用户同时访问同一数据文件
  4. 时间精度:时间精度为秒,不支持毫秒级精度
  5. 计费方式:当前仅支持按小时计费,不支持更复杂的计费规则

常见问题

Q1: 程序无法编译?

A: 检查以下几点:

  • 确保已安装C编译器(GCC/MinGW)
  • 检查源代码文件是否完整
  • 查看编译错误信息,可能是语法错误

Q2: 中文显示乱码?

A:

  • Windows:确保控制台支持UTF-8编码
    • 可以在代码中添加 system("chcp 65001"); 设置UTF-8编码
  • Linux/Mac:设置环境变量 export LANG=zh_CN.UTF-8
  • 或者使用支持UTF-8的终端

Q3: 费用计算不正确?

A:

  • 检查系统时间是否正确
  • 检查配置的每小时费用和免费时长
  • 查看费用计算逻辑是否符合需求
  • 注意:不足一小时按一小时计算

Q4: 车位分配错误?

A:

  • 检查总车位配置是否正确
  • 确保车辆离开时正确释放车位
  • 查看是否有重复的车位分配

Q5: 数据文件无法打开?

A:

  • 检查文件路径是否正确
  • 确保文件没有被其他程序占用
  • 检查文件权限
  • 检查文件编码是否为UTF-8

Q6: 如何修改计费规则?

A:

  • 修改 calculate_fee() 函数
  • 可以改为按分钟计费、分时段计费等
  • 修改后重新编译程序

Q7: 可以导入Excel文件吗?

A:

  • 可以!将Excel文件另存为CSV格式
  • 确保字段顺序与系统要求一致
  • 使用"加载数据文件"功能导入
  • 注意:Excel导出的CSV可能需要调整编码为UTF-8

版本历史

v1.0 (当前版本)

  • 完整的车辆进出管理功能
  • 智能费用计算(支持免费时长)
  • 自动车位分配和释放
  • 停车场状态实时查询
  • 数据查询和统计功能
  • 配置管理功能
  • 数据持久化(CSV格式)
  • 自动备份功能
  • 数据导入导出功能
  • 友好的用户界面(彩色输出、清晰菜单)
  • 详细的代码注释

许可证

本项目仅供学习和教育使用。


开发信息

  • 开发语言:C语言
  • 开发环境:支持Windows/Linux/Mac
  • 编译器要求:GCC 或兼容的C编译器
  • 标准库:C标准库(stdio.h, stdlib.h, string.h, time.h等)

学习建议

本系统适合用于:

  • C语言学习项目
  • 数据结构与算法实践
  • 文件操作练习
  • 控制台程序开发
  • 时间处理练习
  • 业务逻辑实现

可以改进的方向

  1. 数据结构优化

    • 使用链表或树结构支持更大数据量
    • 使用哈希表提高查找效率
    • 使用优先队列优化车位分配
  2. 数据库集成

    • 使用SQLite替代CSV文件
    • 支持更复杂的数据查询
    • 支持事务处理
  3. 图形界面

    • 开发GUI版本(如使用GTK+或Qt)
    • 提供更友好的用户体验
    • 可视化车位状态
  4. 网络功能

    • 支持多用户网络访问
    • 数据云端同步
    • 远程管理功能
  5. 高级功能

    • 会员管理(会员折扣、积分等)
    • 预约停车功能
    • 多种计费方式(分时段、包月等)
    • 车牌识别(图像识别)
    • 自动缴费(移动支付)
  6. 报表功能

    • 自动生成日报、月报、年报
    • 收入统计分析
    • 车位利用率分析
  7. 硬件集成

    • 道闸控制
    • 车牌识别摄像头
    • LED显示屏
    • 语音提示

技术支持

如有问题或建议,请:

  1. 检查本文档的常见问题部分
  2. 查看源代码注释
  3. 检查数据文件格式是否正确
  4. 查看编译错误信息

使用技巧

  1. 合理配置参数

    • 根据实际停车场情况设置总车位数
    • 根据市场行情设置合理的收费标准
    • 设置合适的免费时长(通常15-30分钟)
  2. 定期备份数据

    • 建议每天备份一次数据
    • 重要操作前先备份
    • 保留多个历史备份
  3. 数据整理

    • 定期清理过期的停车记录
    • 保持数据的准确性和完整性
    • 定期检查车位分配是否正确
  4. 统计分析

    • 定期查看统计信息
    • 分析车位利用率
    • 优化停车场管理策略
  5. 导出分析

    • 可以将数据导出为CSV文件
    • 在Excel中进行分析
    • 生成图表和报表

代码结构说明

主要模块

  1. 工具函数模块

    • 颜色控制、清屏、输入输出等基础功能
  2. 配置管理模块

    • 配置文件的加载和保存
    • 配置参数的修改
  3. 数据持久化模块

    • CSV文件的读写
    • 数据备份和恢复
  4. 停车场管理模块

    • 车辆进入和离开
    • 车位分配和释放
    • 费用计算
  5. 查询统计模块

    • 按车牌号查询
    • 显示所有记录
    • 统计信息
  6. 菜单系统模块

    • 主菜单和子菜单
    • 用户交互界面

关键函数说明

  • vehicle_enter(): 车辆进入处理
  • vehicle_exit(): 车辆离开处理
  • calculate_fee(): 费用计算
  • find_free_spot(): 查找空余车位
  • update_free_spots(): 更新空余车位数量
  • show_statistics(): 显示统计信息

源代码

/*
 * 停车场管理系统 v1.0
 * 
 * 功能说明:
 * - 车辆进入停车场(记录车牌号、进入时间、分配车位)
 * - 车辆离开停车场(计算停车费用、释放车位)
 * - 查询停车场状态(空余车位、已停车位等)
 * - 车辆信息查询和管理
 * - 停车记录统计
 * - 数据持久化(CSV格式)
 * - 数据导入导出和备份功能
 * 
 * 编译方法:
 * Windows (MinGW): gcc parking_manager.c -o parking_manager.exe
 * Linux/Mac:      gcc parking_manager.c -o parking_manager
 * 
 * 作者:系统自动生成
 * 日期:2024
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#ifdef _WIN32
#include <windows.h>
#include <conio.h>
#else
#include <termios.h>
#include <unistd.h>
#endif

/* ==================== 常量定义 ==================== */

#define PLATE_LEN 20           // 车牌号最大长度
#define CAR_TYPE_LEN 20        // 车辆类型最大长度
#define MAX_PARKING_SPOTS 1000 // 最大停车位数量
#define MAX_RECORDS 10000      // 最大记录数量
#define DATA_FILE "parking_records.csv"    // 默认数据文件
#define CONFIG_FILE "parking_config.txt"    // 配置文件
#define BACKUP_DIR "backups"                // 备份目录

/* 默认配置 */
#define DEFAULT_TOTAL_SPOTS 100     // 默认总车位
#define DEFAULT_FEE_PER_HOUR 5.0   // 默认每小时费用(元)
#define DEFAULT_FREE_MINUTES 15     // 默认免费时长(分钟)

/* ==================== 数据结构定义 ==================== */

/**
 * 停车记录结构体
 * 记录每辆车的停车信息
 */
typedef struct {
    char plate[PLATE_LEN];         // 车牌号
    char carType[CAR_TYPE_LEN];    // 车辆类型(如:小型车、大型车等)
    int spotNumber;                // 车位号
    time_t enterTime;              // 进入时间(时间戳)
    time_t exitTime;               // 离开时间(时间戳,0表示未离开)
    double fee;                    // 停车费用
    int isDeleted;                 // 删除标记(0=未删除,1=已删除)
} ParkingRecord;

/**
 * 停车场配置结构体
 * 存储停车场的配置信息
 */
typedef struct {
    int totalSpots;                // 总车位数量
    int freeSpots;                  // 当前空余车位
    double feePerHour;              // 每小时费用(元)
    int freeMinutes;                // 免费时长(分钟)
} ParkingConfig;

/* ==================== 全局变量 ==================== */

ParkingRecord records[MAX_RECORDS];  // 停车记录数组
int record_count = 0;                 // 当前记录数量
ParkingConfig config;                 // 停车场配置

/* ==================== 颜色控制函数(Windows平台) ==================== */

#ifdef _WIN32
/**
 * 设置控制台文字颜色(仅Windows平台)
 * @param attr 颜色属性
 */
void set_color(WORD attr) {
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), attr);
}
#define COLOR_RESET  (FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE)
#define COLOR_RED    (FOREGROUND_RED | FOREGROUND_INTENSITY)
#define COLOR_GREEN  (FOREGROUND_GREEN | FOREGROUND_INTENSITY)
#define COLOR_YELLOW (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY)
#define COLOR_CYAN   (FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY)
#define COLOR_BLUE   (FOREGROUND_BLUE | FOREGROUND_INTENSITY)
#else
// Linux/Mac平台的颜色控制(空实现)
void set_color(int attr) { (void)attr; }
#define COLOR_RESET  0
#define COLOR_RED    0
#define COLOR_GREEN  0
#define COLOR_YELLOW 0
#define COLOR_CYAN   0
#define COLOR_BLUE   0
#endif

/* ==================== 工具函数 ==================== */

/**
 * 清屏函数(跨平台)
 */
void clear_screen() {
#ifdef _WIN32
    system("cls");
#else
    system("clear");
#endif
}

/**
 * 暂停程序,等待用户按回车键
 */
void pause_anykey() {
    printf("\n按回车键继续...");
    getchar();
    getchar();
}

/**
 * 去除字符串末尾的换行符
 * @param s 要处理的字符串
 */
void trim_newline(char *s) {
    if (!s) return;
    size_t n = strlen(s);
    if (n > 0 && s[n-1] == '\n') {
        s[n-1] = '\0';
    }
}

/**
 * 从标准输入读取一行文本
 * @param buf 缓冲区
 * @param sz 缓冲区大小
 * @return 成功返回buf指针,失败返回NULL
 */
char* read_line(char *buf, size_t sz) {
    if (!fgets(buf, (int)sz, stdin)) return NULL;
    trim_newline(buf);
    return buf;
}

/**
 * 交互式读取整数输入
 * @param prompt 提示信息
 * @return 读取到的整数值
 */
int read_int(const char *prompt) {
    char buf[64];
    while (1) {
        printf("%s", prompt);
        if (!read_line(buf, sizeof(buf))) return 0;
        if (strlen(buf) == 0) return 0;
        char *end;
        long v = strtol(buf, &end, 10);
        if (end != buf && *end == '\0') return (int)v;
        set_color(COLOR_RED);
        printf("输入无效,请输入整数。\n");
        set_color(COLOR_RESET);
    }
}

/**
 * 交互式读取浮点数输入
 * @param prompt 提示信息
 * @return 读取到的浮点数值
 */
double read_double(const char *prompt) {
    char buf[64];
    while (1) {
        printf("%s", prompt);
        if (!read_line(buf, sizeof(buf))) return 0.0;
        if (strlen(buf) == 0) return 0.0;
        char *end;
        double v = strtod(buf, &end);
        if (end != buf && *end == '\0') return v;
        set_color(COLOR_RED);
        printf("输入无效,请输入数字。\n");
        set_color(COLOR_RESET);
    }
}

/**
 * 验证车牌号格式(简单验证:不能为空)
 * @param plate 车牌号
 * @return 有效返回1,无效返回0
 */
int validate_plate(const char *plate) {
    if (strlen(plate) == 0 || strlen(plate) > PLATE_LEN - 1) return 0;
    return 1;
}

/**
 * 查找正在停车的记录(按车牌号,且未离开)
 * @param plate 车牌号
 * @return 找到返回索引,未找到返回-1
 */
int find_parking_by_plate(const char *plate) {
    for (int i = 0; i < record_count; i++) {
        if (records[i].isDeleted == 0 && 
            records[i].exitTime == 0 &&  // 未离开
            strcmp(records[i].plate, plate) == 0) {
            return i;
        }
    }
    return -1;
}

/**
 * 查找可用的车位号
 * @return 找到返回车位号(1开始),未找到返回-1
 */
int find_free_spot() {
    // 标记已占用的车位
    int occupied[MAX_PARKING_SPOTS] = {0};
    
    for (int i = 0; i < record_count; i++) {
        if (records[i].isDeleted == 0 && records[i].exitTime == 0) {
            // 车辆还在停车场
            if (records[i].spotNumber > 0 && records[i].spotNumber <= MAX_PARKING_SPOTS) {
                occupied[records[i].spotNumber - 1] = 1;
            }
        }
    }
    
    // 查找第一个空余车位
    for (int i = 0; i < config.totalSpots; i++) {
        if (occupied[i] == 0) {
            return i + 1; // 车位号从1开始
        }
    }
    
    return -1; // 没有空余车位
}

/**
 * 计算停车费用
 * @param enterTime 进入时间(时间戳)
 * @param exitTime 离开时间(时间戳)
 * @return 停车费用(元)
 */
double calculate_fee(time_t enterTime, time_t exitTime) {
    if (enterTime == 0 || exitTime == 0) return 0.0;
    if (exitTime <= enterTime) return 0.0;
    
    // 计算停车时长(秒)
    double duration_seconds = difftime(exitTime, enterTime);
    // 转换为分钟
    double duration_minutes = duration_seconds / 60.0;
    
    // 免费时长内不收费
    if (duration_minutes <= config.freeMinutes) {
        return 0.0;
    }
    
    // 计算费用(按小时计费,不足一小时按一小时计算)
    double duration_hours = (duration_minutes - config.freeMinutes) / 60.0;
    if (duration_hours < 0) duration_hours = 0;
    
    // 向上取整到小时
    int hours = (int)(duration_hours);
    if (duration_hours > hours) hours++;
    
    return hours * config.feePerHour;
}

/**
 * 格式化时间显示
 * @param time 时间戳
 * @param buf 输出缓冲区
 * @param size 缓冲区大小
 */
void format_time(time_t time, char *buf, size_t size) {
    if (time == 0) {
        strncpy(buf, "未记录", size - 1);
        buf[size - 1] = '\0';
        return;
    }
    struct tm *tm_info = localtime(&time);
    strftime(buf, size, "%Y-%m-%d %H:%M:%S", tm_info);
}

/**
 * 显示加载动画
 */
void show_loading() {
    printf("\n");
    for (int i = 0; i <= 20; i++) {
        printf("\r系统加载中: [");
        for (int j = 0; j < 20; j++) {
            if (j < i) printf("=");
            else printf(" ");
        }
        printf("] %.0f%%", i * 5.0);
        fflush(stdout);
#ifdef _WIN32
        Sleep(50);
#else
        usleep(50000);
#endif
    }
    printf("\n");
    clear_screen();
}

/**
 * 打印分隔线
 */
void print_separator() {
    printf("===========================================================\n");
}

/**
 * 打印标题
 * @param title 标题文本
 */
void print_title(const char *title) {
    print_separator();
    printf("  %s\n", title);
    print_separator();
}

/* ==================== 函数前向声明 ==================== */

/**
 * 更新空余车位数量(前向声明)
 */
void update_free_spots();

/* ==================== 配置管理函数 ==================== */

/**
 * 初始化默认配置
 */
void init_default_config() {
    config.totalSpots = DEFAULT_TOTAL_SPOTS;
    config.freeSpots = DEFAULT_TOTAL_SPOTS;
    config.feePerHour = DEFAULT_FEE_PER_HOUR;
    config.freeMinutes = DEFAULT_FREE_MINUTES;
}

/**
 * 加载配置文件
 * @return 成功返回1,失败返回0
 */
int load_config() {
    FILE *f = fopen(CONFIG_FILE, "r");
    if (!f) {
        // 文件不存在,使用默认配置
        init_default_config();
        return 0;
    }
    
    char line[256];
    while (fgets(line, sizeof(line), f)) {
        trim_newline(line);
        if (strncmp(line, "totalSpots=", 11) == 0) {
            config.totalSpots = atoi(line + 11);
        } else if (strncmp(line, "feePerHour=", 11) == 0) {
            config.feePerHour = atof(line + 11);
        } else if (strncmp(line, "freeMinutes=", 12) == 0) {
            config.freeMinutes = atoi(line + 12);
        }
    }
    
    fclose(f);
    
    // 计算当前空余车位
    update_free_spots();
    
    return 1;
}

/**
 * 保存配置文件
 * @return 成功返回1,失败返回0
 */
int save_config() {
    FILE *f = fopen(CONFIG_FILE, "w");
    if (!f) return 0;
    
    fprintf(f, "totalSpots=%d\n", config.totalSpots);
    fprintf(f, "feePerHour=%.2f\n", config.feePerHour);
    fprintf(f, "freeMinutes=%d\n", config.freeMinutes);
    
    fclose(f);
    return 1;
}

/**
 * 更新空余车位数量
 */
void update_free_spots() {
    int occupied = 0;
    for (int i = 0; i < record_count; i++) {
        if (records[i].isDeleted == 0 && records[i].exitTime == 0) {
            occupied++;
        }
    }
    config.freeSpots = config.totalSpots - occupied;
}

/* ==================== 数据持久化函数 ==================== */

/**
 * 保存数据到CSV文件
 * @param filename 文件名
 * @return 成功返回1,失败返回0
 */
int save_data(const char *filename) {
    FILE *f = fopen(filename, "w");
    if (!f) {
        set_color(COLOR_RED);
        perror("打开文件写入失败");
        set_color(COLOR_RESET);
        return 0;
    }
    
    // 写入CSV表头
    fprintf(f, "车牌号,车辆类型,车位号,进入时间,离开时间,费用\n");
    
    // 写入所有记录
    for (int i = 0; i < record_count; i++) {
        if (records[i].isDeleted) continue;
        
        ParkingRecord *r = &records[i];
        char enterTimeStr[64], exitTimeStr[64];
        format_time(r->enterTime, enterTimeStr, sizeof(enterTimeStr));
        format_time(r->exitTime, exitTimeStr, sizeof(exitTimeStr));
        
        fprintf(f, "\"%s\",\"%s\",%d,\"%s\",\"%s\",%.2f\n",
                r->plate, r->carType, r->spotNumber,
                enterTimeStr, exitTimeStr, r->fee);
    }
    
    fclose(f);
    return 1;
}

/**
 * 从CSV文件加载数据
 * @param filename 文件名
 * @return 成功返回1,失败返回0
 */
int load_data(const char *filename) {
    FILE *f = fopen(filename, "r");
    if (!f) return 0;
    
    char line[1024];
    int line_no = 0;
    record_count = 0;
    
    while (fgets(line, sizeof(line), f) && record_count < MAX_RECORDS) {
        line_no++;
        trim_newline(line);
        if (line[0] == '\0') continue;
        
        // 跳过表头
        if (line_no == 1 && (strstr(line, "车牌号") != NULL || strstr(line, "plate") != NULL)) {
            continue;
        }
        
        // 解析CSV行
        ParkingRecord r;
        memset(&r, 0, sizeof(r));
        
        // 简单的CSV解析
        char *p = line;
        int field = 0;
        char *start = p;
        int in_quotes = 0;
        char fields[6][256] = {0};
        
        while (*p && field < 6) {
            if (*p == '"') {
                in_quotes = !in_quotes;
            } else if (*p == ',' && !in_quotes) {
                *p = '\0';
                while (*start == '"' || *start == ' ') start++;
                char *end = p - 1;
                while (end > start && (*end == '"' || *end == ' ')) end--;
                *(end + 1) = '\0';
                strncpy(fields[field], start, sizeof(fields[field]) - 1);
                field++;
                start = p + 1;
            }
            p++;
        }
        
        // 处理最后一个字段
        if (field < 6 && *start) {
            while (*start == '"' || *start == ' ') start++;
            char *end = p - 1;
            while (end > start && (*end == '"' || *end == ' ' || *end == '\n')) end--;
            *(end + 1) = '\0';
            strncpy(fields[field], start, sizeof(fields[field]) - 1);
        }
        
        // 填充记录
        if (strlen(fields[0]) > 0) {
            strncpy(r.plate, fields[0], PLATE_LEN - 1);
            strncpy(r.carType, fields[1], CAR_TYPE_LEN - 1);
            r.spotNumber = atoi(fields[2]);
            
            // 解析时间(跨平台兼容)
            struct tm tm_enter = {0}, tm_exit = {0};
            if (strlen(fields[3]) > 0 && strcmp(fields[3], "未记录") != 0) {
                // 使用sscanf解析时间字符串 "YYYY-MM-DD HH:MM:SS"
                if (sscanf(fields[3], "%d-%d-%d %d:%d:%d",
                          &tm_enter.tm_year, &tm_enter.tm_mon, &tm_enter.tm_mday,
                          &tm_enter.tm_hour, &tm_enter.tm_min, &tm_enter.tm_sec) == 6) {
                    tm_enter.tm_year -= 1900;  // tm_year是1900年以来的年数
                    tm_enter.tm_mon -= 1;      // tm_mon是0-11
                    r.enterTime = mktime(&tm_enter);
                }
            }
            if (strlen(fields[4]) > 0 && strcmp(fields[4], "未记录") != 0) {
                if (sscanf(fields[4], "%d-%d-%d %d:%d:%d",
                          &tm_exit.tm_year, &tm_exit.tm_mon, &tm_exit.tm_mday,
                          &tm_exit.tm_hour, &tm_exit.tm_min, &tm_exit.tm_sec) == 6) {
                    tm_exit.tm_year -= 1900;
                    tm_exit.tm_mon -= 1;
                    r.exitTime = mktime(&tm_exit);
                }
            }
            
            r.fee = atof(fields[5]);
            r.isDeleted = 0;
            
            records[record_count++] = r;
        }
    }
    
    fclose(f);
    update_free_spots();
    return 1;
}

/**
 * 备份数据文件
 * @return 成功返回1,失败返回0
 */
int backup_data() {
    time_t t = time(NULL);
    struct tm *tm = localtime(&t);
    char backup_file[256];
    
    // 创建备份目录
#ifdef _WIN32
    system("if not exist backups mkdir backups");
#else
    system("mkdir -p backups");
#endif
    
    snprintf(backup_file, sizeof(backup_file), 
             "%s/backup_%04d%02d%02d_%02d%02d%02d.csv",
             BACKUP_DIR,
             tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
             tm->tm_hour, tm->tm_min, tm->tm_sec);
    
    if (save_data(backup_file)) {
        set_color(COLOR_GREEN);
        printf("备份成功: %s\n", backup_file);
        set_color(COLOR_RESET);
        return 1;
    } else {
        set_color(COLOR_RED);
        printf("备份失败\n");
        set_color(COLOR_RESET);
        return 0;
    }
}

/* ==================== 停车场管理函数 ==================== */

/**
 * 车辆进入停车场
 */
void vehicle_enter() {
    if (config.freeSpots <= 0) {
        set_color(COLOR_RED);
        printf("停车场已满,无法进入!\n");
        set_color(COLOR_RESET);
        return;
    }
    
    if (record_count >= MAX_RECORDS) {
        set_color(COLOR_RED);
        printf("记录数量已达上限\n");
        set_color(COLOR_RESET);
        return;
    }
    
    print_title("车辆进入停车场");
    
    ParkingRecord r;
    memset(&r, 0, sizeof(r));
    
    char buf[256];
    
    // 输入车牌号
    while (1) {
        printf("车牌号*: ");
        if (!read_line(buf, sizeof(buf))) return;
        if (!validate_plate(buf)) {
            set_color(COLOR_RED);
            printf("车牌号不能为空,请重新输入\n");
            set_color(COLOR_RESET);
            continue;
        }
        // 检查是否已在停车场
        if (find_parking_by_plate(buf) != -1) {
            set_color(COLOR_RED);
            printf("该车辆已在停车场内!\n");
            set_color(COLOR_RESET);
            return;
        }
        strncpy(r.plate, buf, PLATE_LEN - 1);
        break;
    }
    
    // 输入车辆类型(可选)
    printf("车辆类型 (如:小型车、大型车等,留空跳过): ");
    read_line(buf, sizeof(buf));
    strncpy(r.carType, buf, CAR_TYPE_LEN - 1);
    
    // 分配车位
    int spot = find_free_spot();
    if (spot == -1) {
        set_color(COLOR_RED);
        printf("没有可用车位!\n");
        set_color(COLOR_RESET);
        return;
    }
    
    r.spotNumber = spot;
    r.enterTime = time(NULL);
    r.exitTime = 0;
    r.fee = 0.0;
    r.isDeleted = 0;
    
    // 添加到记录
    records[record_count++] = r;
    update_free_spots();
    
    set_color(COLOR_GREEN);
    printf("\n车辆进入成功!\n");
    printf("车牌号: %s\n", r.plate);
    printf("车位号: %d\n", r.spotNumber);
    char timeStr[64];
    format_time(r.enterTime, timeStr, sizeof(timeStr));
    printf("进入时间: %s\n", timeStr);
    set_color(COLOR_RESET);
}

/**
 * 车辆离开停车场
 */
void vehicle_exit() {
    print_title("车辆离开停车场");
    
    char plate[PLATE_LEN];
    printf("输入车牌号: ");
    read_line(plate, sizeof(plate));
    
    int idx = find_parking_by_plate(plate);
    if (idx == -1) {
        set_color(COLOR_RED);
        printf("未找到该车辆或车辆已离开!\n");
        set_color(COLOR_RESET);
        return;
    }
    
    ParkingRecord *r = &records[idx];
    
    // 设置离开时间
    r->exitTime = time(NULL);
    
    // 计算费用
    r->fee = calculate_fee(r->enterTime, r->exitTime);
    
    // 显示信息
    printf("\n车辆信息:\n");
    printf("车牌号: %s\n", r->plate);
    printf("车辆类型: %s\n", strlen(r->carType) > 0 ? r->carType : "未填写");
    printf("车位号: %d\n", r->spotNumber);
    
    char enterTimeStr[64], exitTimeStr[64];
    format_time(r->enterTime, enterTimeStr, sizeof(enterTimeStr));
    format_time(r->exitTime, exitTimeStr, sizeof(exitTimeStr));
    printf("进入时间: %s\n", enterTimeStr);
    printf("离开时间: %s\n", exitTimeStr);
    
    // 计算停车时长
    double duration_seconds = difftime(r->exitTime, r->enterTime);
    int hours = (int)(duration_seconds / 3600);
    int minutes = (int)((duration_seconds - hours * 3600) / 60);
    printf("停车时长: %d小时%d分钟\n", hours, minutes);
    
    set_color(COLOR_CYAN);
    printf("停车费用: %.2f 元\n", r->fee);
    set_color(COLOR_RESET);
    
    // 释放车位
    update_free_spots();
    
    set_color(COLOR_GREEN);
    printf("\n车辆离开成功!\n");
    set_color(COLOR_RESET);
}

/**
 * 查询停车场状态
 */
void show_parking_status() {
    print_title("停车场状态");
    
    printf("总车位: %d\n", config.totalSpots);
    printf("已停车位: %d\n", config.totalSpots - config.freeSpots);
    printf("空余车位: %d\n", config.freeSpots);
    printf("使用率: %.1f%%\n", 
           config.totalSpots > 0 ? 
           (double)(config.totalSpots - config.freeSpots) * 100.0 / config.totalSpots : 0.0);
    
    // 显示正在停车的车辆
    int parking_count = 0;
    for (int i = 0; i < record_count; i++) {
        if (records[i].isDeleted == 0 && records[i].exitTime == 0) {
            parking_count++;
        }
    }
    
    if (parking_count > 0) {
        printf("\n正在停车的车辆 (%d 辆):\n", parking_count);
        printf("%-15s %-15s %-8s %-20s\n", "车牌号", "车辆类型", "车位号", "进入时间");
        print_separator();
        
        for (int i = 0; i < record_count; i++) {
            if (records[i].isDeleted == 0 && records[i].exitTime == 0) {
                ParkingRecord *r = &records[i];
                char timeStr[64];
                format_time(r->enterTime, timeStr, sizeof(timeStr));
                printf("%-15s %-15s %-8d %-20s\n",
                       r->plate,
                       strlen(r->carType) > 0 ? r->carType : "-",
                       r->spotNumber,
                       timeStr);
            }
        }
    }
}

/**
 * 按车牌号查询车辆信息
 */
void query_by_plate() {
    print_title("按车牌号查询");
    char plate[PLATE_LEN];
    printf("输入车牌号: ");
    read_line(plate, sizeof(plate));
    
    int found = 0;
    for (int i = 0; i < record_count; i++) {
        if (records[i].isDeleted == 0 && strcmp(records[i].plate, plate) == 0) {
            found = 1;
            ParkingRecord *r = &records[i];
            
            printf("\n车辆信息:\n");
            printf("车牌号: %s\n", r->plate);
            printf("车辆类型: %s\n", strlen(r->carType) > 0 ? r->carType : "未填写");
            printf("车位号: %d\n", r->spotNumber);
            
            char enterTimeStr[64], exitTimeStr[64];
            format_time(r->enterTime, enterTimeStr, sizeof(enterTimeStr));
            format_time(r->exitTime, exitTimeStr, sizeof(exitTimeStr));
            printf("进入时间: %s\n", enterTimeStr);
            
            if (r->exitTime > 0) {
                printf("离开时间: %s\n", exitTimeStr);
                printf("停车费用: %.2f 元\n", r->fee);
            } else {
                printf("状态: 正在停车中\n");
                // 计算当前停车时长
                time_t now = time(NULL);
                double duration_seconds = difftime(now, r->enterTime);
                int hours = (int)(duration_seconds / 3600);
                int minutes = (int)((duration_seconds - hours * 3600) / 60);
                printf("已停车时长: %d小时%d分钟\n", hours, minutes);
            }
            break;
        }
    }
    
    if (!found) {
        set_color(COLOR_RED);
        printf("未找到该车辆记录\n");
        set_color(COLOR_RESET);
    }
}

/**
 * 显示所有停车记录
 */
void show_all_records() {
    print_title("所有停车记录");
    
    int count = 0;
    for (int i = 0; i < record_count; i++) {
        if (records[i].isDeleted == 0) count++;
    }
    
    if (count == 0) {
        printf("暂无停车记录\n");
        return;
    }
    
    printf("共 %d 条记录\n\n", count);
    printf("%-15s %-12s %-8s %-20s %-20s %-10s\n",
           "车牌号", "车辆类型", "车位号", "进入时间", "离开时间", "费用");
    print_separator();
    
    for (int i = 0; i < record_count; i++) {
        if (records[i].isDeleted) continue;
        ParkingRecord *r = &records[i];
        char enterTimeStr[64], exitTimeStr[64];
        format_time(r->enterTime, enterTimeStr, sizeof(enterTimeStr));
        format_time(r->exitTime, exitTimeStr, sizeof(exitTimeStr));
        
        printf("%-15s %-12s %-8d %-20s %-20s %-10.2f\n",
               r->plate,
               strlen(r->carType) > 0 ? r->carType : "-",
               r->spotNumber,
               enterTimeStr,
               r->exitTime > 0 ? exitTimeStr : "停车中",
               r->fee);
    }
}

/**
 * 统计功能
 */
void show_statistics() {
    print_title("统计信息");
    
    // 今日统计
    time_t now = time(NULL);
    struct tm *today = localtime(&now);
    today->tm_hour = 0;
    today->tm_min = 0;
    today->tm_sec = 0;
    time_t today_start = mktime(today);
    
    int today_count = 0;
    double today_income = 0.0;
    int current_parking = 0;
    double total_income = 0.0;
    
    for (int i = 0; i < record_count; i++) {
        if (records[i].isDeleted == 0) {
            if (records[i].enterTime >= today_start) {
                today_count++;
            }
            if (records[i].exitTime >= today_start && records[i].exitTime > 0) {
                today_income += records[i].fee;
            }
            if (records[i].exitTime == 0) {
                current_parking++;
            }
            if (records[i].exitTime > 0) {
                total_income += records[i].fee;
            }
        }
    }
    
    printf("今日统计:\n");
    printf("  进入车辆: %d 辆\n", today_count);
    printf("  今日收入: %.2f 元\n", today_income);
    printf("\n当前状态:\n");
    printf("  正在停车: %d 辆\n", current_parking);
    printf("  空余车位: %d 个\n", config.freeSpots);
    printf("\n累计统计:\n");
    printf("  总收入: %.2f 元\n", total_income);
    printf("  总记录: %d 条\n", record_count);
}

/* ==================== 菜单系统 ==================== */

/**
 * 停车场管理菜单
 */
void parking_management_menu() {
    while (1) {
        clear_screen();
#ifdef _WIN32
        system("color 0B");
#endif
        print_title("停车场管理");
        printf("1. 车辆进入\n");
        printf("2. 车辆离开\n");
        printf("3. 查询停车场状态\n");
        printf("0. 返回主菜单\n");
        
        int c = read_int("\n请选择操作 (0-3): ");
        switch (c) {
            case 1: vehicle_enter(); pause_anykey(); break;
            case 2: vehicle_exit(); pause_anykey(); break;
            case 3: show_parking_status(); pause_anykey(); break;
            case 0: return;
            default:
                set_color(COLOR_RED);
                printf("无效选择\n");
                set_color(COLOR_RESET);
                pause_anykey();
                break;
        }
    }
}

/**
 * 查询菜单
 */
void query_menu() {
    while (1) {
        clear_screen();
#ifdef _WIN32
        system("color 0B");
#endif
        print_title("数据查询");
        printf("1. 按车牌号查询\n");
        printf("2. 显示所有记录\n");
        printf("3. 统计信息\n");
        printf("0. 返回主菜单\n");
        
        int c = read_int("\n请选择操作 (0-3): ");
        switch (c) {
            case 1: query_by_plate(); pause_anykey(); break;
            case 2: show_all_records(); pause_anykey(); break;
            case 3: show_statistics(); pause_anykey(); break;
            case 0: return;
            default:
                set_color(COLOR_RED);
                printf("无效选择\n");
                set_color(COLOR_RESET);
                pause_anykey();
                break;
        }
    }
}

/**
 * 系统设置菜单
 */
void settings_menu() {
    while (1) {
        clear_screen();
#ifdef _WIN32
        system("color 0B");
#endif
        print_title("系统设置");
        printf("1. 查看配置\n");
        printf("2. 修改配置\n");
        printf("3. 保存数据\n");
        printf("4. 备份数据\n");
        printf("5. 加载数据文件\n");
        printf("6. 导出CSV文件\n");
        printf("0. 返回主菜单\n");
        
        int c = read_int("\n请选择操作 (0-6): ");
        switch (c) {
            case 1: {
                printf("\n当前配置:\n");
                printf("总车位: %d\n", config.totalSpots);
                printf("每小时费用: %.2f 元\n", config.feePerHour);
                printf("免费时长: %d 分钟\n", config.freeMinutes);
                pause_anykey();
                break;
            }
            case 2: {
                printf("\n修改配置:\n");
                int total = read_int("总车位数量: ");
                if (total > 0 && total <= MAX_PARKING_SPOTS) {
                    config.totalSpots = total;
                    update_free_spots();
                }
                double fee = read_double("每小时费用 (元): ");
                if (fee >= 0) {
                    config.feePerHour = fee;
                }
                int free = read_int("免费时长 (分钟): ");
                if (free >= 0) {
                    config.freeMinutes = free;
                }
                save_config();
                set_color(COLOR_GREEN);
                printf("配置已保存\n");
                set_color(COLOR_RESET);
                pause_anykey();
                break;
            }
            case 3:
                if (save_data(DATA_FILE)) {
                    set_color(COLOR_GREEN);
                    printf("保存成功\n");
                    set_color(COLOR_RESET);
                } else {
                    set_color(COLOR_RED);
                    printf("保存失败\n");
                    set_color(COLOR_RESET);
                }
                pause_anykey();
                break;
            case 4:
                backup_data();
                pause_anykey();
                break;
            case 5: {
                char fname[260];
                printf("输入要加载的文件名 (默认 %s): ", DATA_FILE);
                read_line(fname, sizeof(fname));
                if (strlen(fname) == 0) strcpy(fname, DATA_FILE);
                if (load_data(fname)) {
                    set_color(COLOR_GREEN);
                    printf("加载成功,共 %d 条记录\n", record_count);
                    set_color(COLOR_RESET);
                } else {
                    set_color(COLOR_RED);
                    printf("加载失败或文件不存在\n");
                    set_color(COLOR_RESET);
                }
                pause_anykey();
                break;
            }
            case 6: {
                char fname[260];
                printf("导出文件名 (默认 %s): ", DATA_FILE);
                read_line(fname, sizeof(fname));
                if (strlen(fname) == 0) strcpy(fname, DATA_FILE);
                if (save_data(fname)) {
                    set_color(COLOR_GREEN);
                    printf("导出成功: %s\n", fname);
                    set_color(COLOR_RESET);
                } else {
                    set_color(COLOR_RED);
                    printf("导出失败\n");
                    set_color(COLOR_RESET);
                }
                pause_anykey();
                break;
            }
            case 0: return;
            default:
                set_color(COLOR_RED);
                printf("无效选择\n");
                set_color(COLOR_RESET);
                pause_anykey();
                break;
        }
    }
}

/**
 * 主菜单
 */
int main_menu() {
    while (1) {
        clear_screen();
#ifdef _WIN32
        system("color 0B");
#endif
        print_title("停车场管理系统 v1.0");
        printf("1. 停车场管理\n");
        printf("2. 数据查询\n");
        printf("3. 系统设置\n");
        printf("0. 退出系统\n");
        
        int c = read_int("\n请选择操作 (0-3): ");
        switch (c) {
            case 1: parking_management_menu(); break;
            case 2: query_menu(); break;
            case 3: settings_menu(); break;
            case 0: return 0;
            default:
                set_color(COLOR_RED);
                printf("无效选择\n");
                set_color(COLOR_RESET);
                pause_anykey();
                break;
        }
    }
}

/* ==================== 主函数 ==================== */

/**
 * 程序入口
 * @return 程序退出码
 */
int main() {
#ifdef _WIN32
    system("color 0B");
#endif
    
    // 显示加载动画
    show_loading();
    
    // 加载配置
    if (load_config()) {
        set_color(COLOR_GREEN);
        printf("已加载配置文件\n");
        set_color(COLOR_RESET);
    } else {
        init_default_config();
        set_color(COLOR_YELLOW);
        printf("使用默认配置\n");
        set_color(COLOR_RESET);
    }
    
    // 尝试加载数据文件
    if (load_data(DATA_FILE)) {
        set_color(COLOR_GREEN);
        printf("已加载数据文件 %s,共 %d 条记录\n", DATA_FILE, record_count);
        set_color(COLOR_RESET);
    } else {
        set_color(COLOR_YELLOW);
        printf("未找到数据文件,使用空数据\n");
        set_color(COLOR_RESET);
    }
    
    pause_anykey();
    
    // 进入主菜单
    main_menu();
    
    // 退出前询问是否保存
    printf("\n是否保存数据到 %s ? (Y/N): ", DATA_FILE);
    char ans[8];
    read_line(ans, sizeof(ans));
    if (ans[0] == 'Y' || ans[0] == 'y') {
        if (save_data(DATA_FILE)) {
            set_color(COLOR_GREEN);
            printf("保存成功\n");
            set_color(COLOR_RESET);
        } else {
            set_color(COLOR_RED);
            printf("保存失败\n");
            set_color(COLOR_RESET);
        }
    }
    
    // 保存配置
    save_config();
    
    printf("\n感谢使用停车场管理系统!\n");
    return 0;
}



祝您使用愉快!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员春至

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值