You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

汽车租赁程序取消预约功能异常:CSV数据错乱与空行问题

汽车租赁取消预约功能问题修复

问题描述

  1. 初始文件空行问题:rented_cars.csv开头出现异常空行,内容如下:
,,,,
3,123456Z,Tue May 07 01:00:00 2024,Wed May 08 01:00:00 2024,200.00$
3,789123B,Tue May 07 01:00:00 2024,Wed May 08 01:00:00 2024,100.00$
  1. 取消预约后日期异常:用户3取消车牌为123456Z的预约后,文件中日期变为1970年初始时间,格式错乱:
,,,Thu Jan 01 02:00:07 1970,
3,789123B,Thu Jan 01 02:00:00 1970, Thu Jan 01 02:00:07 1970,

问题根源分析

1. 初始空行与CSV格式问题

  • appendRentInfoToCSV函数中错误地对字符串类型的TotalPriceForTheRent使用fixed << setprecision(2)数值格式化符,导致输出异常,可能产生空字段或乱码。
  • 文件打开模式使用ios::out | ios::app,ios::out的截断逻辑与ios::app追加逻辑冲突,可能导致写入行为异常。

2. 取消后日期变1970问题

  • cancelRESERVATION函数仅从文件读取预约信息用于显示,但未将文件中的日期字符串解析为time_t类型更新到rents数组,导致数组中RentStartDate和RentEndDate字段未初始化(值为0),转换后对应1970年初始时间。

修复方案

1. 修复CSV写入格式问题

修改appendRentInfoToCSV函数,移除无效的数值格式化符,调整文件打开模式:

void appendRentInfoToCSV(const RentInformation& rentInfo) {
    // 仅使用ios::app实现追加写入,避免截断冲突
    ofstream outputFile("C:\\Users\\User\\Desktop\\rented_cars.csv", ios::app);
    if (outputFile.is_open()) {
        char startDateStr[50];
        char endDateStr[50];

        strftime(startDateStr, sizeof(startDateStr), "%a %b %d %H:%M:%S %Y", localtime(&rentInfo.RentStartDate));
        strftime(endDateStr, sizeof(endDateStr), "%a %b %d %H:%M:%S %Y", localtime(&rentInfo.RentEndDate));

        // 移除针对字符串的数值格式化符,直接输出字符串
        outputFile << rentInfo.ClientID << ',' << rentInfo.CarPlateNumber << ','
                   << startDateStr << ',' << endDateStr << ','
                   << rentInfo.TotalPriceForTheRent << endl;
        cout << "Reservation information added successfully." << endl;
        outputFile.close();
    } else {
        cerr << "Failed to open file for writing." << endl;
    }
}

2. 修复日期同步问题

添加日期字符串转time_t的辅助函数,并在cancelRESERVATION中同步加载文件数据到rents数组:

辅助函数:字符串转时间戳

time_t stringToTime(const string& dateStr) {
    struct tm tm = {};
    // 匹配CSV中的日期格式
    strptime(dateStr.c_str(), "%a %b %d %H:%M:%S %Y", &tm);
    return mktime(&tm);
}

修改取消预约函数

void cancelRESERVATION(CarsInformation cars[], int& numCars, RentInformation rents[], int& numRents, UserInformation users[], int& numUsers, string userID) {
    ifstream inputFile("C:\\Users\\User\\Desktop\\rented_cars.csv");
    if (!inputFile.is_open()) {
        cerr << "Failed to open file for reading." << endl;
        return;
    }

    bool hasReservations = false;
    int j = 1;
    string line;
    // 清空数组,重新从文件加载最新数据
    numRents = 0;
    while (getline(inputFile, line)) {
        stringstream ss(line);
        string field;
        string fields[5];
        int fieldIndex = 0;
        while (getline(ss, field, ',')) {
            if (fieldIndex < 5) {
                fields[fieldIndex++] = field;
            }
        }

        // 跳过空行或格式错误的行
        if (fieldIndex != 5 || fields[0].empty()) {
            continue;
        }

        // 将文件数据解析到rents数组
        RentInformation rent;
        rent.ClientID = fields[0];
        rent.CarPlateNumber = fields[1];
        rent.RentStartDate = stringToTime(fields[2]);
        rent.RentEndDate = stringToTime(fields[3]);
        rent.TotalPriceForTheRent = fields[4];
        rents[numRents++] = rent;

        if (fields[0] == userID) {
            cout << "Car #" << j++ << endl;
            cout << "Plate Number: " << fields[1] << endl;
            cout << "Start Date: " << fields[2] << endl;
            cout << "End Date: " << fields[3] << endl;
            cout << "Total Price: " << fields[4] << endl;
            hasReservations = true;
        }
    }
    inputFile.close();

    if (!hasReservations) {
        cout << "You have no reservations to cancel." << endl;
        return;
    }

    string plateNumber;
    cout << "Enter the plate number of the car you want to cancel the reservation for: ";
    cin >> plateNumber;

    int index = -1;
    for (int i = 0; i < numRents; i++) {
        if (rents[i].CarPlateNumber == plateNumber && rents[i].ClientID == userID) {
            index = i;
            break;
        }
    }

    if (index != -1) {
        // 移除指定预约记录
        for (int i = index; i < numRents - 1; i++) {
            rents[i] = rents[i + 1];
        }
        numRents--;

        // 更新车辆可用性
        for (int i = 0; i < numCars; i++) {
            if (cars[i].plateNumber == plateNumber) {
                cars[i].availability = "available";
                break;
            }
        }

        // 写入cars.csv
        ofstream outputFile("C:\\Users\\User\\Desktop\\cars.csv");
        if (outputFile.is_open()) {
            for (int i = 0; i < numCars; i++) {
                outputFile << cars[i].type << ',' << cars[i].brand << ',' << cars[i].model << ',' << cars[i].year << ',' << cars[i].subType << ',' << cars[i].color << ',' << cars[i].plateNumber << ',' << cars[i].price << ',' << cars[i].availability << endl;
            }
            outputFile.close();
            cout << "Car availability updated successfully." << endl;
        } else {
            cerr << "Failed to open file for writing." << endl;
        }

        // 写入rented_cars.csv,移除无效格式化符
        ofstream outputFile2("C:\\Users\\User\\Desktop\\rented_cars.csv");
        if (outputFile2.is_open()) {
            for (int i = 0; i < numRents; i++) {
                char startDateStr[50];
                char endDateStr[50];

                strftime(startDateStr, sizeof(startDateStr), "%a %b %d %H:%M:%S %Y", localtime(&rents[i].RentStartDate));
                strftime(endDateStr, sizeof(endDateStr), "%a %b %d %H:%M:%S %Y", localtime(&rents[i].RentEndDate));

                outputFile2 << rents[i].ClientID << ',' << rents[i].CarPlateNumber << ','
                            << startDateStr << ',' << endDateStr << ','
                            << rents[i].TotalPriceForTheRent << endl;
            }
            outputFile2.close();
            cout << "Updated reservation information written to the CSV file." << endl;
        } else {
            cerr << "Failed to open file for writing." << endl;
        }

        cout << "Reservation canceled successfully." << endl;
    } else {
        cout << "Reservation not found for the provided plate number." << endl;
    }
}

额外注意事项

  • 确保rents数组有足够存储空间,避免越界;
  • 可添加strptime解析失败的错误处理(如返回0时提示日期格式错误);
  • 历史遗留的空行可手动删除,修复后的代码会自动跳过格式错误的行。

内容的提问来源于stack exchange,提问作者Elie ISSA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 09:53:09