基于Jsoncpp实现C++多JSON字符串完整比较的最佳方案问询
Hey there! I've dealt with exactly this kind of JSON comparison task using Jsoncpp before, so let's walk through the best approach to get this done right. The core idea is recursive traversal since JSON is inherently nested (objects, arrays, primitive types), and we need to validate every single part of the structure and values.
1. Build a Recursive Helper Function
First, create a helper function that takes two Json::Value objects and checks for full equality. This function will handle all JSON types by prioritizing type checks first, then diving into nested structures:
#include <JsonCpp/json.h> #include <vector> #include <algorithm> #include <string> #include <cmath> bool compareJson(const Json::Value& a, const Json::Value& b) { // First, check if types match (critical for full content comparison) if (a.type() != b.type()) { return false; } // Handle primitive types switch(a.type()) { case Json::nullValue: return true; // Both are null, so equal case Json::intValue: return a.asInt() == b.asInt(); case Json::uintValue: return a.asUInt() == b.asUInt(); case Json::realValue: // Use epsilon to handle floating-point precision errors return std::abs(a.asDouble() - b.asDouble()) < 1e-9; case Json::stringValue: return a.asString() == b.asString(); case Json::booleanValue: return a.asBool() == b.asBool(); // Handle arrays case Json::arrayValue: { if (a.size() != b.size()) return false; // Different lengths = not equal for (Json::ArrayIndex i = 0; i < a.size(); ++i) { if (!compareJson(a[i], b[i])) return false; } return true; } // Handle objects case Json::objectValue: { Json::Value::Members keysA = a.getMemberNames(); Json::Value::Members keysB = b.getMemberNames(); if (keysA.size() != keysB.size()) return false; // Different key counts // Sort keys to ignore order (skip this if strict key order matters) std::sort(keysA.begin(), keysA.end()); std::sort(keysB.begin(), keysB.end()); if (keysA != keysB) return false; // Mismatched key names // Compare values for each key for (const std::string& key : keysA) { if (!compareJson(a[key], b[key])) return false; } return true; } default: return false; // Unknown type, default to not equal } }
2. Extend to Multiple JSONs
To compare two or more parsed JSONs, use the helper function to check all against a baseline (the first JSON in the list):
bool compareMultipleJson(const std::vector<Json::Value>& jsons) { if (jsons.size() < 2) { // Edge case: 0 or 1 JSONs are trivially "equal" (adjust if needed) return true; } // Use the first JSON as the reference point const Json::Value& baseline = jsons[0]; for (size_t i = 1; i < jsons.size(); ++i) { if (!compareJson(baseline, jsons[i])) { return false; } } return true; }
Key Notes for Your Project
- Type Strictness: The code treats different numeric types (e.g.,
intvsuintvsdouble) as distinct, which aligns with "full data content" comparison. If you need to relax this (e.g., consider 5 and 5.0 equal), modify the numeric cases to convert all values todoublebefore comparing. - Floating-Point Precision: The
1e-9epsilon is a safe default, but tweak it based on how precise your numeric values need to be. - Key Order: If your use case requires strict key order matching (even though JSON specs say objects are unordered), remove the
std::sortcalls for the key lists. - Special Values: If your JSONs might include
NaNorInfinity, add checks usingstd::isnanandstd::isinfsince direct equality checks on these values will fail.
内容的提问来源于stack exchange,提问作者Bishal Sahoo

