写作以jsoncpp(c ++)

时间:2015-06-15 04:47:45

标签: c++ json jsoncpp

考虑以下示例,我的来源是

    Json::Value root;
    root["id"]=0;
            Json::Value text;
            text["first"]="i";
            text["second"]="love";
            text["third"]="you";
    root["text"]=text;
    root["type"]="test";
    root["begin"]=1;
    root["end"]=1;
    Json::StyledWriter writer;
    string strJson=writer.write(root);
    cout<<"JSON WriteTest" << endl << strJson <<endl;

我以为我会按照行的顺序写json字段。相反,结果是:

JSON WriteTest
{
   "begin" : 1,
   "end" : 1,
   "id" : 0,
   "text" : {
      "first" : "i",
      "second" : "love",
      "third" : "you"
   },
   "type" : "test"
}

我希望json格式是

JSON WriteTest
{
   "id" : 0,
   "text" : {
      "first" : "i",
      "second" : "love",
      "third" : "you"
   },
   "type" : "test"
   "begin" : 1,
   "end" : 1,
}

如何撰写Json订单?

4 个答案:

答案 0 :(得分:2)

不,我认为你不能。 JsonCpp将其值保存在std::map<CZString, Value>中,该值始终按CZString比较排序。因此,它不知道您添加项目的原始订单。

答案 1 :(得分:0)

我有办法可以解决你的问题。你要试试吗?我的解决方案是你使用boost/property_tree/json_parser.hpp,输出是你想要的格式!关于我的代码:

#include <boost/property_tree/json_parser.hpp>
#include <sstream>
#include <iostream>

using namespace std;
int main()
{
    boost::property_tree::ptree parser, child;
    parser.put("id", 0);
    child.put("first", "i");
    child.put("second", "love");
    child.put("third", "you");
    parser.put_child("text", child);
    parser.put("type", "test");
    parser.put("begin", 1);
    parser.put("end", 1);
    stringstream ss;
    boost::property_tree::json_parser::write_json(ss, parser);
    cout << ss.str() << endl;
    return 0;
}

在运行代码之前,您应该安装boost 1.57。代码在gcc 4.7中运行良好,提升1.57.输出为{&#34; id&#34; :0,&#34; text&#34; :{&#34; first&#34; :&#34;我&#34;,&#34;第二&#34; :&#34;爱&#34;,&#34;第三&#34; :&#34;你&#34; },&#34;输入&#34; :&#34;测试&#34; &#34;开始&#34; :1,&#34;结束&#34; :1,}。关于boost::property_tree::ptree,您可以点击here。它使用list<pair<key, ptree>>来保存数据。因此它保存了无序数据,除非您调用了list.sort()。我希望这可以帮到你。

答案 2 :(得分:0)

对象中的键值对将始终排序。 Json数组没有排序,它们由一系列没有键的值组成。 对象,作为数组中括号内的键值对的命名集合(数组),将保留其位置,例如

{
"adressen" : [
  {
     "start" : {
        "ID" : 1,
        "key" : "2352KJ25",
        "lat" : 52.157225922529967,
        "lon" : 4.5298663828345527
     }
  },
  {
     "eind" : {
        "ID" : 2,
        "key" : "2352KJ25",
        "lat" : 52.157225922529967,
        "lon" : 4.5298663828345527
     }
  }
}

ID,key,lat,lon已排序,但start和eind位于其原始位置。 所以,至少你的第一,第二,第三可能是

Json::Value text(Json::arrayValue);
text.append("I");
text.append("love");
text.append("you");

不需要第一,第二和第三个标签! 也许这可以帮助您找到解决方法。

答案 3 :(得分:0)

The Dark所述, JsonCpp 将其值保存在std::map<CZString, Value>中,该CZString始终按CZString比较排序,而不会同时跟踪您在输出中添加项目或所需订单的原始订单。

但你可以使用这个&#34;隐藏的功能&#34;在你的利益。我的意思是,你只需要按照所需的顺序按照&#34; natural&#34; std::string sortedStr(Json::Value & value, std::vector<std::string> sortKeys) { Json::Value sortedValue; // The JSON object to store the new (sorted) hash char newKey[60]; // I use C expressions, modify to C++ if you like // Build new sortedValue int i = 0; for (auto & key : sortKeys) { sprintf(newKey, "SORTEDKEY:%03d-%s", i++, key.c_str()); sortedValue[newKey] = value[key]; } // Write to string, should be sorted on primary keys Json::StyledWriter w; std::string result = w.write(sortedValue); // Remove aux. tags from primary keys std::size_t pos = 0; while ((pos = result.find("SORTEDKEY:", pos)) != std::string::npos) { result.erase(pos, 14); } return result; } 的顺序。我在我的JSONCPP包装器类中有一个方法来执行此操作。转换为简单函数的快速代码将是这样的:

std::string sortedObjStr = sortedValue(myValue, {"first", "second", "third", "fourth"});

要使用它,只需致电:

img = Image.open("./color/1.jpg")
width =  img.size[0]
height = img.size[1]
colors = img.getcolors(width*height)

请注意:

  • 我将它用于相对较小的对象(配置数据)。
  • 我使用&#34;标签&#34; SORTEDKEY,因为这不会出现在我的数据中的任何地方。根据您的需要进行修改。
  • 我不检查所使用的密钥是否存在。您可以添加此支票。
  • 您也可以使用它来生成原始对象的受限,有序子集。