JsonCpp生成JSON时大小写敏感排序异常问题求助
解决JsonCpp键排序大小写问题的方案
JsonCpp默认采用ASCII值排序,这就导致大写字母开头的键会排在小写字母开头的键前面(因为大写字母ASCII码值小于小写)。针对你遇到的ShuttersOpen、ShutterType、ShutterWidth排序不符合预期的问题,你可以通过自定义键比较函数替换默认排序逻辑来解决。
方法1:实现不区分大小写的字母排序
如果你希望按键的自然字母顺序排序(忽略大小写),可以定义一个将键转换为小写后再比较的函数:
#include <json/json.h> #include <algorithm> #include <cctype> // 自定义比较器:不区分大小写的字符串比较 bool caseInsensitiveKeyCompare(const std::string& a, const std::string& b) { std::string aLower, bLower; std::transform(a.begin(), a.end(), std::back_inserter(aLower), ::tolower); std::transform(b.begin(), b.end(), std::back_inserter(bLower), ::tolower); return aLower < bLower; } int main() { Json::Value root; root["ShuttersOpen"] = true; root["ShutterType"] = "Roller"; root["ShutterWidth"] = 120; // 应用自定义比较器 Json::Value::setObjectKeysComparator(caseInsensitiveKeyCompare); // 输出格式化JSON Json::StyledWriter writer; std::cout << writer.write(root) << std::endl; return 0; }
这段代码会将所有键转为小写后比较,输出的键顺序为ShutterType、ShuttersOpen、ShutterWidth,符合自然字母排序逻辑。
方法2:严格字典序排序(支持本地化规则)
如果需要遵循严格的字典序(比如考虑本地化的字母排序规则),可以使用std::lexicographical_compare配合本地化字符处理:
#include <json/json.h> #include <algorithm> #include <locale> // 严格字典序比较器 bool strictLexicographicalCompare(const std::string& a, const std::string& b) { std::locale loc; return std::lexicographical_compare( a.begin(), a.end(), b.begin(), b.end(), [&](char c1, char c2) { return std::tolower(c1, loc) < std::tolower(c2, loc); } ); } int main() { Json::Value root; root["ShuttersOpen"] = true; root["ShutterType"] = "Roller"; root["ShutterWidth"] = 120; Json::Value::setObjectKeysComparator(strictLexicographicalCompare); Json::StyledWriter writer; std::cout << writer.write(root) << std::endl; return 0; }
关键注意事项
setObjectKeysComparator是全局设置,调用后所有后续创建的Json::Value都会使用该比较器。若仅需针对特定对象生效,可先保存默认比较器:auto defaultCmp = Json::Value::getObjectKeysComparator();,处理完目标对象后再设置回去。- 该功能要求JsonCpp版本在1.7.0及以上,若使用旧版本建议升级到最新稳定版。
内容的提问来源于stack exchange,提问作者marhyno
相关产品推荐
相关产品推荐

