C++读取|分隔文本文件并存入值为list的std::map的实现问题
实现方案
你原有代码存在两个核心问题:
last指针初始为nullptr,直接传给std::from_chars会触发未定义行为,需要把起始位置设为字符串的首地址- 找到第一个分隔符提取key之后,没有对剩余内容做拆分逻辑,无法生成对应的list值
以下是可直接运行的实现代码:
#include <iostream> #include <fstream> #include <map> #include <list> #include <string> #include <charconv> int main() { // 明确list元素类型,此处默认用std::string存储所有后续字段,有类型转换需求可自行调整 std::map<int, std::list<std::string>> sample_map; std::ifstream in("file.txt"); if (!in.is_open()) { std::cerr << "文件打开失败" << std::endl; return 1; } std::string line; while (std::getline(in, line)) { if (line.empty()) continue; // 跳过空行 // 第一步:提取第一个字段作为key size_t first_delim_pos = line.find('|'); if (first_delim_pos == std::string::npos) continue; // 无分隔符的非法行直接跳过 int key = 0; auto conv_res = std::from_chars(line.data(), line.data() + first_delim_pos, key); if (conv_res.ec != std::errc()) continue; // key数值转换失败的非法行跳过 // 第二步:拆分剩余字段存入list std::list<std::string> value_list; size_t last_pos = first_delim_pos + 1; size_t next_delim_pos = line.find('|', last_pos); while (next_delim_pos != std::string::npos) { value_list.emplace_back(line.substr(last_pos, next_delim_pos - last_pos)); last_pos = next_delim_pos + 1; next_delim_pos = line.find('|', last_pos); } // 插入行末尾的最后一个字段 value_list.emplace_back(line.substr(last_pos)); // 插入map,题目已说明第一个值唯一,无需判重 sample_map[key] = std::move(value_list); } // 可选:测试输出验证结果 for (const auto& entry : sample_map) { std::cout << "Key: " << entry.first << " Values: "; for (const auto& val : entry.second) { std::cout << val << " "; } std::cout << std::endl; } return 0; }
可选调整方案
如果你后续的字段都是整数类型,可以把map定义改为std::map<int, std::list<int>>,拆分部分替换为如下代码即可:
std::list<int> value_list; size_t last_pos = first_delim_pos + 1; size_t next_delim_pos = line.find('|', last_pos); while (next_delim_pos != std::string::npos) { int val = 0; auto val_conv = std::from_chars(line.data() + last_pos, line.data() + next_delim_pos, val); if (val_conv.ec == std::errc()) { value_list.push_back(val); } last_pos = next_delim_pos + 1; next_delim_pos = line.find('|', last_pos); } // 处理最后一个字段 int last_val = 0; auto last_conv = std::from_chars(line.data() + last_pos, line.data() + line.size(), last_val); if (last_conv.ec == std::errc()) { value_list.push_back(last_val); }
内容的提问来源于stack exchange,提问作者cosmo
相关产品推荐
相关产品推荐

