如何用C++按列名读取文本文件指定列值并通过Setter方法存储?
实现按列名读取并调用Setter方法的解决方案
我来给你梳理下核心实现思路,再附上适配你需求的完整改进代码:
核心思路拆解
- 第一步:解析表头建立映射:先读取第一行的列名(ProductA、ProductB这类),把每个列名和对应的列索引存在一个
map<string, int>里,这样后面读取数据时能快速通过列名定位到对应列的位置。 - 第二步:定义产品数据类:创建一个类封装每个产品的属性,同时提供对应的Setter方法(比如
setProductA),让数据存储更规范,也完全匹配你调用Setter的需求。 - 第三步:逐行读取匹配Setter:读取每行数据时,借助之前建立的列索引映射,把对应列的值传入对应的Setter方法,把每行数据封装成一个产品对象,最后统一存在容器里管理。
完整改进代码
#include <iomanip> #include <iostream> #include <fstream> #include <sstream> #include <string> #include <map> #include <vector> // 定义产品数据类,包含属性和对应的Setter方法 class ProductData { private: double productA; double productB; double productC; public: void setProductA(double val) { productA = val; } void setProductB(double val) { productB = val; } void setProductC(double val) { productC = val; } // 方便打印验证结果的方法 void print() const { std::cout << std::left << std::setw(8) << productA << std::setw(8) << productB << std::setw(8) << productC << std::endl; } }; int main() { std::string line; std::ifstream fileIN("input.txt"); if (fileIN.fail()) { std::cerr << "无法打开目标文件!" << std::endl; exit(1); } // 读取表头,建立列名与索引的映射关系 std::map<std::string, int> columnMap; if (std::getline(fileIN, line)) { std::istringstream headerStream(line); std::string columnName; int colIndex = 0; while (headerStream >> columnName) { columnMap[columnName] = colIndex++; } } // 读取数据行,调用Setter存储数据 std::vector<ProductData> productList; while (std::getline(fileIN, line)) { std::istringstream dataStream(line); std::vector<double> rowData; double val; // 先把整行数据读取到vector中暂存 while (dataStream >> val) { rowData.push_back(val); } // 创建产品对象,根据列映射调用对应Setter ProductData product; if (columnMap.count("ProductA") && columnMap["ProductA"] < rowData.size()) { product.setProductA(rowData[columnMap["ProductA"]]); } if (columnMap.count("ProductB") && columnMap["ProductB"] < rowData.size()) { product.setProductB(rowData[columnMap["ProductB"]]); } if (columnMap.count("ProductC") && columnMap["ProductC"] < rowData.size()) { product.setProductC(rowData[columnMap["ProductC"]]); } productList.push_back(product); } // 打印读取结果验证 std::cout << "读取到的产品数据:" << std::endl; std::cout << std::left << std::setw(8) << "ProductA" << std::setw(8) << "ProductB" << std::setw(8) << "ProductC" << std::endl; for (const auto& p : productList) { p.print(); } fileIN.close(); return 0; }
关键细节说明
- 数据类型修正:把原来的
int改成double,避免浮点数转整数丢失精度(你的数据里有23.3、45.2这类小数)。 - 灵活容器替代数组:用
vector存储每行数据和产品对象,比固定大小的数组更适配行数、列数不固定的场景。 - 容错处理:用
columnMap.count()判断列名是否存在,同时检查索引是否在当前行数据范围内,避免越界错误。 - 扩展性:后续如果新增产品列,只需要在
ProductData类里添加对应的属性和Setter方法即可,不需要大幅修改核心逻辑。
内容的提问来源于stack exchange,提问作者Nll
相关产品推荐
相关产品推荐

