C++实现CSV文件指定行列数据提取并导出新文件
嘿,作为初学者你已经会循环和读文件,那这个提取CSV特定行列的任务完全可以搞定!我给你写个完整的示例代码,再一步步解释关键部分,保证你能看懂。
核心思路
咱们要做的事儿拆解下来就是这几步:
- 打开原始CSV文件和要输出的新CSV文件
- 逐行读取原始文件,跳过前8行(因为你要从第9行开始),读到第789行就停止处理
- 对每一行,把它分割成单独的列数据
- 提取第67到890列(注意:代码里的索引是从0开始的,所以要转换成
66到889的索引范围) - 把提取的列用逗号拼接起来,写入新文件
完整代码示例
#include <iostream> #include <fstream> #include <string> #include <vector> // 分割CSV行的工具函数:把一行按逗号拆成列 std::vector<std::string> splitCSVLine(const std::string& line) { std::vector<std::string> columns; std::string currentColumn; for (char c : line) { if (c == ',') { columns.push_back(currentColumn); currentColumn.clear(); } else { currentColumn += c; } } // 别忘了添加最后一列 columns.push_back(currentColumn); return columns; } int main() { // 原始文件路径和新文件路径,你可以改成自己的路径 std::string inputPath = "original.csv"; std::string outputPath = "extracted_data.csv"; // 打开文件 std::ifstream inputFile(inputPath); std::ofstream outputFile(outputPath); if (!inputFile.is_open()) { std::cerr << "Error: 无法打开原始文件!" << std::endl; return 1; } if (!outputFile.is_open()) { std::cerr << "Error: 无法创建输出文件!" << std::endl; return 1; } std::string line; int currentLine = 0; const int startLine = 9; // 你要的起始行(1-based) const int endLine = 789; // 你要的结束行(1-based) const int startCol = 67; // 你要的起始列(1-based) const int endCol = 890; // 你要的结束列(1-based) // 转换为0-based索引 int startIdxCol = startCol - 1; int endIdxCol = endCol - 1; while (std::getline(inputFile, line)) { currentLine++; // 跳过起始行之前的内容 if (currentLine < startLine) { continue; } // 超过结束行就停止 if (currentLine > endLine) { break; } // 分割当前行成列 std::vector<std::string> columns = splitCSVLine(line); // 检查列数是否足够,避免越界 if (columns.size() <= endIdxCol) { std::cerr << "Warning: 第" << currentLine << "行列数不足,跳过该行!" << std::endl; continue; } // 提取指定列并拼接成新行 std::string newLine; for (int i = startIdxCol; i <= endIdxCol; i++) { if (i != startIdxCol) { newLine += ","; } newLine += columns[i]; } // 写入新文件,别忘了换行 outputFile << newLine << std::endl; } // 关闭文件 inputFile.close(); outputFile.close(); std::cout << "数据提取完成!新文件已保存为: " << outputPath << std::endl; return 0; }
关键部分解释
行列索引转换:
你说的第9行、第67列是日常的1-based计数,但C++里容器(比如vector)是从0开始索引的,所以要减去1转换成startLine-1和startCol-1,这样才不会取错数据。CSV分割函数:
这个splitCSVLine函数是基础版,假设你的CSV里没有带逗号的单元格(比如"张三,李四"这种带引号的情况)。如果你的文件有这种复杂格式,咱们可以再调整,但先处理最常见的简单情况。循环控制:
用currentLine变量计数每一行,小于起始行就跳过,大于结束行就直接退出循环,避免处理多余的内容,节省时间。越界检查:
加了一个判断,如果当前行的列数不够你要提取的结束列,就跳过该行并打印警告,防止程序崩溃。
示例验证(你提到的小例子)
如果要提取第2-3列、第2-3行,只需要修改代码里的这几个参数:
const int startLine = 2; // 起始行改成2 const int endLine = 3; // 结束行改成3 const int startCol = 2; // 起始列改成2 const int endCol = 3; // 结束列改成3
假设原始文件是:
姓名,年龄,性别,城市 张三,25,男,北京 李四,30,女,上海 王五,28,男,广州
运行代码后,新文件extracted_data.csv的内容就是:
25,男 30,女
完全符合你的要求!
内容的提问来源于stack exchange,提问作者user9322960
相关产品推荐
相关产品推荐

