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

如何对读取到struct的CSV数据按员工数列执行选择排序?代码故障求助

问题分析与代码修正

你的代码在CSV读取、排序逻辑上存在多处问题,导致无法正常运行,下面逐一指出并给出修正方案:

一、CSV读取部分的问题与修复

存在的问题:

  • 循环终止条件与分隔符错误:用!inputFile.eof()判断循环会导致最后一行重复读取;若你的CSV是Excel默认的逗号分隔格式,却用'|'作为getline终止符,会把整行拆成错误片段。
  • 无意义的内部循环:for (int i = 0; i < 1e4; i++)会反复读取同一个stringstream,导致vector插入大量重复数据。
  • 字符串读取截断:用>>读取字段时,遇到空格就停止,无法正确读取带空格的字段(比如公司名称、描述)。
  • 变量命名混乱:swimmer与业务逻辑不符,建议改为org或organization提升可读性。

修复后的读取代码:

假设CSV字段用逗号分隔,带空格的字段用双引号包裹(Excel导出标准格式),这里实现简单的CSV字段解析:

#include <vector>
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
#include <algorithm>

// 确保Details结构体定义正确,number_of_employees改为整数类型
struct Details {
    int index;
    std::string organization_Id;
    std::string name;
    std::string website;
    std::string country;
    std::string description;
    int founded;
    std::string industry;
    int number_of_employees; // 关键:用int存储员工数,而非string
};

// 辅助函数:解析CSV单个字段(处理带引号的情况)
std::string parseCSVField(std::stringstream& ss) {
    std::string field;
    char c;
    ss >> c;
    if (c == '"') {
        // 读取带引号的字段,直到下一个双引号
        while (ss.get(c) && c != '"') {
            field += c;
        }
        // 跳过引号后的逗号
        ss.ignore();
    } else {
        // 普通字段,读取到逗号为止
        ss.putback(c);
        std::getline(ss, field, ',');
    }
    return field;
}

std::vector<Details> readCSV(const std::string& filePath) {
    std::vector<Details> results;
    std::ifstream inputFile(filePath);
    if (!inputFile.is_open()) {
        std::cerr << "无法打开目标文件!" << std::endl;
        return results;
    }

    std::string line;
    // 跳过表头(如果CSV包含表头)
    std::getline(inputFile, line);

    while (std::getline(inputFile, line)) {
        std::stringstream ss(line);
        Details org;

        // 逐个解析字段并转换类型
        org.index = std::stoi(parseCSVField(ss));
        org.organization_Id = parseCSVField(ss);
        org.name = parseCSVField(ss);
        org.website = parseCSVField(ss);
        org.country = parseCSVField(ss);
        org.description = parseCSVField(ss);
        org.founded = std::stoi(parseCSVField(ss));
        org.industry = parseCSVField(ss);
        org.number_of_employees = std::stoi(parseCSVField(ss));

        results.push_back(org);
    }
    inputFile.close();
    return results;
}

二、选择排序部分的问题与修复

存在的问题:

  • 数据类型错误:员工数是数值,用string存储会导致字符串比较逻辑错误(比如"100"字符串小于"99",但数值上100更大)。
  • 参数不够灵活:接受数组参数不如直接用vector<Details>&,避免手动处理指针和大小,更安全。
  • 代码可读性差:minvalue = data[minindex = index].number_of_employees把赋值和取值写在一起,易出错。

修复后的排序代码:

void selectionSort(std::vector<Details>& data) {
    int size = data.size();
    for (int startScan = 0; startScan < size - 1; startScan++) {
        int minIndex = startScan;
        int minValue = data[startScan].number_of_employees;

        for (int index = startScan + 1; index < size; index++) {
            if (data[index].number_of_employees < minValue) {
                minIndex = index;
                minValue = data[index].number_of_employees;
            }
        }

        // 直接用std::swap交换元素,简洁安全
        std::swap(data[minIndex], data[startScan]);
    }
}

三、排序后保存到新CSV

添加保存函数,将排序后的数据写入新文件:

void saveCSV(const std::vector<Details>& data, const std::string& filePath) {
    std::ofstream outputFile(filePath);
    if (!outputFile.is_open()) {
        std::cerr << "无法创建输出文件!" << std::endl;
        return;
    }

    // 写入表头
    outputFile << "index,organization_id,name,website,country,description,founded,industry,number_of_employees\n";

    for (const auto& org : data) {
        // 带空格的字段用双引号包裹,符合CSV标准
        outputFile << org.index << ","
                   << "\"" << org.organization_Id << "\","
                   << "\"" << org.name << "\","
                   << "\"" << org.website << "\","
                   << "\"" << org.country << "\","
                   << "\"" << org.description << "\","
                   << org.founded << ","
                   << "\"" << org.industry << "\","
                   << org.number_of_employees << "\n";
    }
    outputFile.close();
}

四、主函数调用示例

int main() {
    std::vector<Details> orgs = readCSV("C:/Users/Mubashra Zaman/Downloads/organizations-100.csv");
    if (orgs.empty()) {
        std::cerr << "未读取到有效数据!" << std::endl;
        return 1;
    }

    selectionSort(orgs);
    saveCSV(orgs, "C:/Users/Mubashra Zaman/Downloads/sorted_organizations.csv");

    std::cout << "排序完成并已保存到新文件!" << std::endl;
    return 0;
}

内容的提问来源于stack exchange,提问作者Mub Malik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 04:00:29