C++ nlohmann json库字段顺序问题及原文件顺序保留方法咨询
JSON字段读取顺序与原文件不一致的问题
原始JSON文件
{ "args":{"value":"192.168.30.4", "desc":"multi uhd device address args"}, "file":{"value":"usrp_samples.dat", "desc":"output file"}, "type":{"value":"short", "desc":"sample type: double, float or short"}, "nsamps":{"value":"0", "desc":"total number of samples to recv"} }
用于读取的C++代码
#include <iostream> #include <fstream> #include <nlohmann/json.hpp> #include <string> using json = nlohmann::json; int main() { // Read from the JSON file using parse std::ifstream file("test3a.json"); if (file.is_open()) { json json_data = json::parse(file); // Iterate over the keys of the JSON object for (auto it = json_data.begin(); it != json_data.end(); ++it) { // Accessing values from each key-value pair std::string key = it.key(); json value = it.value(); // Displaying the read data std::cout << "Input Var: " << key << std::endl; std::cout << " Value: " << value["value"] << std::endl; std::cout << " Desc : " << value["desc"] << std::endl; } std::cout << cmd_line << std::endl; } else { std::cerr << "Error opening file." << std::endl; } }
实际输出结果
Input Var: args Value: "192.168.30.4" Desc : "multi uhd device address args" Input Var: file Value: "usrp_samples.dat" Desc : "output file" Input Var: nsamps Value: "0" Desc : "total number of samples to recv" Input Var: type Value: "short" Desc : "sample type: double, float or short"
疑问
- 出现该现象的原因是什么?
- 是否类似Python字典无固定顺序?
- 能否强制输出顺序与原JSON文件一致?
解答
1. 顺序颠倒的原因
nlohmann/json库默认的json对象基于无序哈希容器(比如std::unordered_map)实现,它不会保留JSON文件里的原始键顺序。迭代时的顺序由容器内部的哈希算法决定,和原始数据的书写顺序无关,因此会出现type和nsamps顺序颠倒的情况。
2. 和Python字典的对比
是的,和Python 3.7版本之前的字典行为完全一致——这类无序关联容器不维护元素的插入/原始顺序,遍历顺序由内部规则(哈希值排序)决定,和数据的原始排列无关。Python 3.7及之后的字典才开始默认保留插入顺序。
3. 强制保留原始顺序的方法
可以通过两种方式实现:
方式一:使用有序JSON对象类型
将代码中的using json = nlohmann::json;替换为:
using json = nlohmann::ordered_json;
ordered_json基于有序容器(比如std::map或std::vector)实现,会严格保留解析JSON时的键顺序,和原文件的顺序完全一致。
方式二:解析时指定保留顺序的标志
在调用json::parse时,传入keep_order解析标志:
json json_data = json::parse(file, nullptr, false, json::parse_flag::keep_order);
这样普通的json对象也会保留原始文件中的键顺序。
内容的提问来源于stack exchange,提问作者user1245262
相关产品推荐
相关产品推荐

