C++使用toml++修改TOML文件指定值报错解决方法
问题原因
两个问题均来自toml++的API使用方式错误:
- 编译错误:通过
[]访问toml表得到的是toml::node_view类型,该类型的赋值运算符不支持直接接收裸int、const char*等字面量作为右值,直接写=1会找不到匹配的operator=重载。 - 字符串赋值不生效:
- 链式访问
["config_paths"]["DIAAI_core"]时,如果config_paths节点不存在、或者存在但不是table类型,赋值操作不会自动创建中间嵌套表,赋值会静默失败 toml::parse_file解析得到的是内存中的表副本,仅将内容输出到cout,没有写回磁盘文件的话,磁盘上的原toml文件自然不会有变化
- 链式访问
- 原代码的额外bug:catch块里构造
std::runtime_error时没有加throw,异常不会向外抛出;函数声明返回json类型,原逻辑没有对应返回值。
修复代码
json ConfigService::getAllData(std::string filePath) { try { toml::table _data_table = toml::parse_file(filePath); // 获取config_paths节点的可写表引用,不存在则自动创建空表 toml::table& config_paths = _data_table["config_paths"].ref<toml::table>(); // 插入/修改键值,直接传入对应类型的值即可 config_paths.insert_or_assign("DIAAI_core", std::string_view("diaaiSetting.toml")); // 整数赋值同理 config_paths.insert_or_assign("test_int", 1); std::cout << _data_table << std::endl; // 如果需要把修改持久化到原文件,打开文件流写回 std::ofstream out_file(filePath); out_file << _data_table; out_file.close(); // 按函数声明返回对应的json对象,根据自身业务逻辑做转换即可 return {}; } catch (const toml::parse_error& err) { std::cerr << "Parsing failed:\n" << err.what() << "\n"; throw std::runtime_error(err.what()); } }
如果确认config_paths节点一定存在,也可以用更简洁的链式赋值写法,注意用toml::value显式包装右值即可通过编译:
_data_table["config_paths"]["DIAAI_core"] = toml::value{"diaaiSetting.toml"}; _data_table["config_paths"]["test_int"] = toml::value{1};
注意事项
- 不要直接给
node_view传裸字面量赋值,要么先取到对应类型节点的引用用insert_or_assign,要么用toml::value包装右值 - 嵌套访问节点时,不确定中间节点类型/是否存在的话,优先用
ref<目标类型>()获取引用,会自动创建缺失的节点,避免静默失败 - toml++解析失败抛出的异常类型是
toml::parse_error,直接捕获该类型可以拿到错误位置、源文件引用等更详细的调试信息
内容的提问来源于stack exchange,提问作者Bugsfounder
相关产品推荐
相关产品推荐

