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

从CSV读取数据存入哈希表后,string转float失败(stof抛出异常)

问题分析与修复

核心错误原因

你的代码里内部while循环逻辑完全错误——每次用getline(s, data[i], ',')读取一个字段后,立刻就给stu结构体赋值,这时候data数组还没读满5个元素(比如第一次循环只读到data[0],data[1]到data[4]都是空值或乱码),用stof(data[4])转换空字符串或无效内容,必然抛出std::invalid_argument异常。

另外还可能存在CSV格式问题:比如某行字段数量不足5个,或者score字段不是合法浮点数(包含空格、字母等),也会触发该错误。

修复方案

1. 修正读取逻辑:先读完整行字段,再赋值

把内部while循环改为仅负责读取所有字段到data数组,等整行5个字段全部读取完成后,再进行哈希计算和结构体赋值。

2. 增加数据校验

  • 检查每行读取的字段数量是否为5,避免数组越界和无效数据。
  • 捕获stof的转换异常,防止程序直接崩溃,同时定位错误行。

3. 细节优化

  • 遵循C++标准,将main函数改为返回int类型。
  • 初始化stu数组,避免输出时出现乱码。
  • 修改display函数,只输出有数据的位置,减少无效空行。

修改后的完整代码

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <bits/stdc++.h>
using namespace std;

struct student {
    string id;
    string name;
    string gender;
    string department;
    float score;
};
// 初始化数组,避免默认值乱码
student stu[2000] = {};

int hash_function(string s){
    int total = 0;
    for(int i=0; i<s.size(); i++){
        total += (int)s[i];
    }
    return total % 2000;
}

void display(){
    for(int i=0; i<2000; i++){
        // 只输出有数据的位置,避免大量空行
        if(!stu[i].id.empty()){
            cout << "Position " << i << ": " << stu[i].id << " " << stu[i].name << " " 
                 << stu[i].gender << " " << stu[i].department << " " << stu[i].score << endl;
        }
    }
}

int main(){ // 标准main返回int
    fstream myfile;
    string line;
    string data[5];

    myfile.open("I3list.csv", ios::in);
    if(!myfile.is_open()){ // 检查文件是否成功打开
        cerr << "无法打开文件!" << endl;
        return 1;
    }

    while(getline(myfile, line)){
        int i = 0;
        stringstream s(line);
        // 先把整行的所有字段读入data数组
        while(getline(s, data[i], ',') && i < 5){
            i++;
        }
        // 校验字段数量是否为5
        if(i != 5){
            cerr << "无效行,字段数量不对:" << line << endl;
            continue;
        }
        // 所有字段读取完成,开始处理
        int index = hash_function(data[1]);
        stu[index].id = data[0];
        stu[index].name = data[1];
        stu[index].gender = data[2];
        stu[index].department = data[3];
        // 捕获stof转换异常
        try{
            stu[index].score = stof(data[4]);
        } catch(const std::invalid_argument& e){
            cerr << "分数转换失败,行内容:" << line << endl;
            cerr << "错误信息:" << e.what() << endl;
            // 设置默认值避免后续出错
            stu[index].score = 0.0f;
        } catch(const std::out_of_range& e){
            cerr << "分数超出范围,行内容:" << line << endl;
            cerr << "错误信息:" << e.what() << endl;
            stu[index].score = 0.0f;
        }
    }
    display();
    myfile.close();
    return 0;
}

额外注意事项

  • 确保CSV文件每行都是5个字段,用英文逗号分隔,无多余空格或换行。
  • 如果CSV存在带逗号的字段(比如名字包含逗号),这种简单的按逗号分割方式会失效,需要更专业的CSV解析逻辑,但普通格式场景下上述代码足够使用。

内容的提问来源于stack exchange,提问作者Ly Makara

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:35:56