C++读取CSV中map<uint64_t,std::u16string>键值对及bad_alloc报错解决
C++ 读取包含map<uint64_t, std::u16string>字段的CSV文件解决方案
报错根因
- 空容器非法访问:你定义的
std::map<uint64_t, std::u16string> myMap未填充任何数据,直接对myMap.begin()解引用属于未定义行为,访问非法内存地址触发std::bad_alloc报错。 - 执行逻辑颠倒:你当前的执行顺序是先操作空map做编码转换,再读文件,正确逻辑应该是先读取CSV文件内容,解析填充map后再做编码转换输出。
- 接口调用逻辑错误:
file.ReadFile的第二个参数如果是接收文件内容的输出变量,你传入了未分配足够空间的val,也会触发内存分配错误。
完整实现代码
#include <fstream> #include <string> #include <map> #include <codecvt> #include <locale> #include <iostream> #include <regex> #include <stdexcept> // 读取整个文件内容到std::string std::string read_full_file(const std::string& file_path) { std::ifstream ifs(file_path); if (!ifs.is_open()) { throw std::runtime_error("failed to open file: " + file_path); } return std::string((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>()); } int main() { try { // 1. 读取CSV全部内容 std::string csv_content = read_full_file("你的CSV文件路径.csv"); // 2. 解析value字段的map内容,适配示例格式:{123:u"98"} std::map<uint64_t, std::u16string> myMap; std::regex value_regex(R"(value:\{(\d+):u\"([^\"]+)\"\})"); std::smatch match; if (std::regex_search(csv_content, match, value_regex)) { uint64_t key = std::stoull(match[1].str()); std::string val_utf8 = match[2].str(); // utf8转u16string存入map std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter; std::u16string val_u16 = converter.from_bytes(val_utf8); myMap[key] = val_u16; } // 3. 转换编码后输出到终端 std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter; for (const auto& pair : myMap) { std::string val_utf8 = converter.to_bytes(pair.second); std::cout << "key: " << pair.first << ", value: " << val_utf8 << std::endl; } } catch (const std::exception& e) { std::cerr << "error: " << e.what() << std::endl; return 1; } return 0; }
注意事项
- 如果CSV包含多行数据,可按换行符拆分后循环解析每一行的字段即可。
- 如果你使用的C版本高于等于C17,编译器会提示
codecvt相关接口已弃用,可添加编译选项-Wno-deprecated-declarations忽略警告,也可替换为第三方编码转换库实现相同能力。 - 正则匹配逻辑可根据你实际的CSV字段格式调整,示例正则仅适配你给出的示例数据格式。
内容的提问来源于stack exchange,提问作者Lakshmi Chinta
相关产品推荐
相关产品推荐

