C++如何按列解析CSV文件并将各列数据保存至数组
按列解析CSV的实现方案
核心逻辑
- 先读取第一行表头,拆分得到所有列标识,同时确定总列数
- 定义按列存储的容器:
std::vector<std::vector<double>> column_data,外层索引对应列序号,内层存储对应列的所有数值 - 逐行读取后续内容,拆分每行的字段后,将每个字段转换为浮点型,依次追加到对应列的容器中
完整可运行代码
#include <iostream> #include <fstream> #include <vector> #include <string> #include <sstream> #include <cmath> // 拆分字符串函数,按指定分隔符拆分 std::vector<std::string> split(const std::string& s, char delimiter) { std::vector<std::string> tokens; std::string token; std::istringstream tokenStream(s); while (std::getline(tokenStream, token, delimiter)) { // 去掉字段前后空格,适配格式不规范的CSV size_t start = token.find_first_not_of(" \t"); size_t end = token.find_last_not_of(" \t"); if (start == std::string::npos) { tokens.push_back(""); // 空字段标记 } else { tokens.push_back(token.substr(start, end - start + 1)); } } return tokens; } // 按列读取CSV,返回列名数组和按列存储的数值数组 void read_csv_by_column(const std::string& filename, char delimiter, std::vector<std::string>& column_names, std::vector<std::vector<double>>& column_data) { std::ifstream inFile(filename); std::string line; if (!inFile.is_open()) { std::cout << "Unable to open the file" << std::endl; exit(1); } // 读取第一行表头 if (std::getline(inFile, line)) { column_names = split(line, delimiter); // 如果你的CSV第一列是行号(和示例一致),保留下面这句删除首字段,没有则注释 column_names.erase(column_names.begin()); // 初始化列数据容器 column_data.resize(column_names.size()); } // 读取后续数据行 while (std::getline(inFile, line)) { std::vector<std::string> fields = split(line, delimiter); // 和表头逻辑对应,有行号列则保留下面这句,没有则注释 if (fields.size() > 0) { fields.erase(fields.begin()); } // 遍历每个字段,存入对应列 for (size_t i = 0; i < fields.size() && i < column_data.size(); ++i) { if (fields[i].empty()) { column_data[i].push_back(NAN); // 空值存为NAN,可根据需求修改 } else { column_data[i].push_back(std::stod(fields[i])); } } } inFile.close(); } int main() { std::string filename = "Data.csv"; // 请根据实际CSV分隔符调整:逗号填','、制表符填'\t'、纯空格分隔填' ' char delimiter = ','; std::vector<std::string> column_names; std::vector<std::vector<double>> column_data; read_csv_by_column(filename, delimiter, column_names, column_data); // 示例:输出S0001列所有值 std::cout << "列名:" << column_names[0] << " 的数值如下:" << std::endl; for (double val : column_data[0]) { if (!std::isnan(val)) { std::cout << val << std::endl; } else { std::cout << "空值" << std::endl; } } // 示例:计算S0001列平均值 double sum = 0.0; int count = 0; for (double val : column_data[0]) { if (!std::isnan(val)) { sum += val; count++; } } if (count > 0) { std::cout << column_names[0] << " 列的平均值为:" << sum / count << std::endl; } return 0; }
注意事项
- 若CSV没有示例中的行号列,删除代码中两处
erase语句即可 - 空单元格默认存储为
NAN,计算时可以通过std::isnan过滤,也可根据业务需求修改空值处理逻辑
内容的提问来源于stack exchange,提问作者Cyan
相关产品推荐
相关产品推荐

