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

如何在C++中将CSV数据读取到结构体向量的指针中?

如何在C++中将CSV数据读取到结构体的向量中?

我来帮你搞定这个CSV解析的问题!你已经完成了开头读取列名的部分,现在只需要在循环里把每一行的字段解析到你的Csv结构体里,再塞进向量里就行。

核心思路是:把每一行的字符串流拆分成单个字段,将前四个字段转换成浮点数赋值给结构体的a-d成员,最后一个字段直接作为字符串赋值给e,再把这个结构体对象添加到你的向量指针指向的容器中。

修改后的完整代码如下(重点看数据读取的循环部分):

#include <vector>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <stdexcept> // 可选,用于异常处理

struct Csv{
 float a;
 float b;
 float c;
 float d;
 std::string e;
};

int main(){
 std::string colname;
 std::ifstream *myFile = new std::ifstream("iris.csv");
 std::vector<Csv> *csv = new std::vector<Csv>;
 std::string line;

 // Read the column names
 if(myFile->good()) {
     std::getline(*myFile, line);
     std::stringstream ss(line);
     while(std::getline(ss, colname, ',')){
         std::cout<<colname<<std::endl;
     }
 }

 // Read data, line by line
 while(std::getline(*myFile, line)) {
     std::stringstream ss(line);
     Csv row; // 创建一个临时结构体对象存储当前行数据
     std::string field;

     try {
         // 解析第一个浮点数字段
         std::getline(ss, field, ',');
         row.a = std::stof(field);
         // 解析第二个浮点数字段
         std::getline(ss, field, ',');
         row.b = std::stof(field);
         // 解析第三个浮点数字段
         std::getline(ss, field, ',');
         row.c = std::stof(field);
         // 解析第四个浮点数字段
         std::getline(ss, field, ',');
         row.d = std::stof(field);
         // 解析最后一个字符串字段(无逗号分隔,读到行尾)
         std::getline(ss, field);
         row.e = field;

         // 将当前行数据加入向量
         csv->push_back(row);
     } catch (const std::invalid_argument& e) {
         // 处理转换失败的情况,比如字段不是合法的浮点数
         std::cerr << "Invalid data format in line: " << line << std::endl;
         std::cerr << "Error: " << e.what() << std::endl;
         continue;
     } catch (const std::out_of_range& e) {
         std::cerr << "Number out of range in line: " << line << std::endl;
         std::cerr << "Error: " << e.what() << std::endl;
         continue;
     }
 }

 // 可选:测试输出读取到的数据
 std::cout << "\nRead " << csv->size() << " rows of data:" << std::endl;
 for(const auto& item : *csv) {
     std::cout << item.a << ", " << item.b << ", " << item.c << ", " << item.d << ", " << item.e << std::endl;
 }

 // 记得释放动态分配的内存
 delete myFile;
 delete csv;

 return 0;
}

几个关键细节说明:

  • 用std::getline(ss, field, ',')按逗号拆分每个字段,前四个字段通过std::stof转换成浮点数。
  • 最后一个字段直接用std::getline(ss, field),因为Iris数据集的最后一列是类别名称,没有逗号分隔,直接读取到行尾即可。
  • 加入了异常处理(try-catch块),可以处理数据格式错误的情况,避免程序崩溃。
  • 最后别忘了释放你用new分配的ifstream和vector内存,避免内存泄漏。

另外提一句:其实在C++里,除非特别需要,一般不需要用new创建这些对象,直接用栈上的对象(比如std::ifstream myFile("iris.csv");和std::vector<Csv> csv;)会更简单安全,也不用手动释放内存。不过既然你指定要用指针,上面的代码就保持了你的写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 19:52:27