nlohmann json for modern C++

【1】作者简介

【2】库

https://github.com/nlohmann/json

【3】应用示例

(1)工程配置

(2)示例代码

  1 #include <string>
  2 #include <vector>
  3 #include <fstream>
  4 #include <iostream>
  5 #include <iomanip>
  6 
  7 // 为了调试中文显示
  8 #pragma execution_character_set("utf-8")
  9 
 10 #include "nlohmann/json.hpp"
 11 // for convenience
 12 using json = nlohmann::json;
 13 
 14 void json_object()
 15 {
 16     // create a JSON object
 17     json j =
 18     {
 19         {"pi", 3.141},
 20         {"happy", true},
 21         {"name", "Niels"},
 22         {"nothing", nullptr},
 23         {
 24             "answer", {
 25                 {"everything", 42}
 26             }
 27         },
 28         {"list", {1, 0, 2}},
 29         {
 30             "object", {
 31                 {"currency", "USD"},
 32                 {"value", 42.99}
 33             }
 34         }
 35     };
 36 
 37     // add new values
 38     j["new"]["key"]["value"] = { "another", "list" };
 39 
 40     // count elements
 41     auto s = j.size();
 42     j["size"] = s;
 43 
 44     // pretty print with indent of 4 spaces
 45     std::cout << std::setw(4) << j << '\n';
 46 
 47     // create JSON values
 48     json j_boolean = true;
 49     json j_number_integer = 17;
 50     json j_number_float = 23.42;
 51     json j_object = { {"one", 1}, {"two", 2} };
 52     json j_object_empty(json::value_t::object);
 53     json j_array = { 1, 2, 4, 8, 16 };
 54     json j_array_empty(json::value_t::array);
 55     json j_string = "Hello, world";
 56 
 57     // call back()
 58     std::cout << j_boolean.back() << '\n';
 59     std::cout << j_number_integer.back() << '\n';
 60     std::cout << j_number_float.back() << '\n';
 61     std::cout << j_object.back() << '\n';
 62     //std::cout << j_object_empty.back() << '\n';  // undefined behavior
 63     std::cout << j_array.back() << '\n';
 64     //std::cout << j_array_empty.back() << '\n';   // undefined behavior
 65     std::cout << j_string.back() << '\n';
 66 
 67     // back() called on a null value
 68     try
 69     {
 70         json j_null;
 71         j_null.back();
 72     }
 73     catch (json::invalid_iterator & e)
 74     {
 75         std::cout << e.what() << '\n';
 76     }
 77 }
 78 
 79 void json_arry()
 80 {
 81     // create JSON arrays
 82     json j_no_init_list = json::array();
 83     json j_empty_init_list = json::array({});
 84     json j_nonempty_init_list = json::array({ 1, 2, 3, 4 });
 85     json j_list_of_pairs = json::array({ {"one", 1}, {"two", 2} });
 86 
 87     // serialize the JSON arrays
 88     std::cout << j_no_init_list << '\n';
 89     std::cout << j_empty_init_list << '\n';
 90     std::cout << j_nonempty_init_list << '\n';
 91     std::cout << j_list_of_pairs << '\n';
 92 }
 93 
 94 void json_object_at_key()
 95 {
 96     // create JSON object
 97     json object =
 98     {
 99         {"the good", "il buono"},
100         {"the bad", "il cattivo"},
101         {"the ugly", "il brutto"}
102     };
103 
104     // output element with key "the ugly"
105     std::cout << object.at("the ugly") << '\n';
106 
107     // change element with key "the bad"
108     object.at("the bad") = "liuy kaizen";
109     object.at("the good") = 100;
110 
111     // output changed array
112     std::cout << object << '\n';
113 
114     // exception type_error.304
115     try
116     {
117         // use at() on a non-object type
118         json j_str = "I am a string";
119         std::cout << j_str << '\n';
120         j_str.at("the good") = "Another string";
121 
122         const json jc_str = "I am a const json object";
123         std::cout << jc_str << "\n";
124         // jc_str.at("the good") = "Const string"; const对象,禁止赋值
125     }
126     catch (json::type_error & e)
127     {
128         std::cout << e.what() << '\n';
129     }
130 
131     // exception out_of_range.401
132     try
133     {
134         // try to write at a nonexisting key
135         object.at("the fast") = "il rapido";
136     }
137     catch (json::out_of_range & e)
138     {
139         std::cout << e.what() << '\n';
140     }
141 }
142 
143 void json_array_at_index()
144 {
145     // create JSON array
146     json array = { "first", "2nd", "third", "fourth" };
147 
148     // output element at index 2 (third element)
149     std::cout << array.at(2) << '\n';
150 
151     // change element at index 1 (second element) to "second"
152     array.at(1) = "second";
153 
154     // output changed array
155     std::cout << array << '\n';
156 
157     // exception type_error.304
158     try
159     {
160         // use at() on a non-array type
161         json str = "I am a string";
162         str.at(0) = "Another string";
163     }
164     catch (json::type_error & e)
165     {
166         std::cout << e.what() << '\n';
167     }
168 
169     // exception out_of_range.401
170     try
171     {
172         // try to write beyond the array limit
173         array.at(5) = "sixth";
174     }
175     catch (json::out_of_range & e)
176     {
177         std::cout << e.what() << '\n';
178     }
179 }
180 
181 void json_at_pointer()
182 {
183     // create a JSON value
184     json j =
185     {
186         {"number", 1}, {"string", "foo"}, {"array", {1, 2}}
187     };
188 
189     // read-only access
190 
191     // output element with JSON pointer "/number"
192     std::cout << j.at("/number"_json_pointer) << '\n';
193     // output element with JSON pointer "/string"
194     std::cout << j.at("/string"_json_pointer) << '\n';
195     // output element with JSON pointer "/array"
196     std::cout << j.at("/array"_json_pointer) << '\n';
197     // output element with JSON pointer "/array/0"
198     std::cout << j.at("/array/0"_json_pointer) << '\n';
199     // output element with JSON pointer "/array/1"
200     std::cout << j.at("/array/1"_json_pointer) << '\n';
201 
202     // writing access
203 
204     // change the string
205     j.at("/string"_json_pointer) = "bar";
206     // output the changed string
207     std::cout << j["string"] << '\n';
208 
209     // change an array element
210     j.at("/array/1"_json_pointer) = 21;
211     // output the changed array
212     std::cout << j["array"] << '\n';
213 
214     // out_of_range.106
215     try
216     {
217         // try to use an array index with leading '0'
218         json::reference ref = j.at("/array/01"_json_pointer);
219     }
220     catch (json::parse_error & e)
221     {
222         std::cout << e.what() << '\n';
223     }
224 
225     // out_of_range.109
226     try
227     {
228         // try to use an array index that is not a number
229         json::reference ref = j.at("/array/one"_json_pointer);
230     }
231     catch (json::parse_error & e)
232     {
233         std::cout << e.what() << '\n';
234     }
235 
236     // out_of_range.401
237     try
238     {
239         // try to use a an invalid array index
240         json::reference ref = j.at("/array/4"_json_pointer);
241     }
242     catch (json::out_of_range & e)
243     {
244         std::cout << e.what() << '\n';
245     }
246 
247     // out_of_range.402
248     try
249     {
250         // try to use the array index '-'
251         json::reference ref = j.at("/array/-"_json_pointer);
252     }
253     catch (json::out_of_range & e)
254     {
255         std::cout << e.what() << '\n';
256     }
257 
258     // out_of_range.403
259     try
260     {
261         // try to use a JSON pointer to an nonexistent object key
262         json::const_reference ref = j.at("/foo"_json_pointer);
263     }
264     catch (json::out_of_range & e)
265     {
266         std::cout << e.what() << '\n';
267     }
268 
269     // out_of_range.404
270     try
271     {
272         // try to use a JSON pointer that cannot be resolved
273         json::reference ref = j.at("/number/foo"_json_pointer);
274     }
275     catch (json::out_of_range & e)
276     {
277         std::cout << e.what() << '\n';
278     }
279 }
280 
281 void json_compare()
282 {
283     // create a JSON array
284     json j1 = { "one", "two", 3, 4.5, false };
285 
286     // create a copy
287     json j2(j1);
288 
289     // serialize the JSON array
290     std::cout << j1 << " = " << j2 << '\n';
291     std::cout << std::boolalpha << (j1 == j2) << '\n';
292 }
293 
294 void json_list_init()
295 {
296     // create JSON values
297     json j_empty_init_list = json({});
298     json j_object = { {"one", 1}, {"two", 2} };
299     json j_array = { 1, 2, 3, 4 };
300     json j_nested_object = { {"one", {1}}, {"two", {1, 2}} };
301     json j_nested_array = { {{1}, "one"}, {{1, 2}, "two"} };
302 
303     // serialize the JSON value
304     std::cout << j_empty_init_list << '\n';    // {}
305     std::cout << j_object << '\n';             // {"one":1,"two":2}
306     std::cout << j_array << '\n';              // [1,2,3,4]
307     std::cout << j_nested_object << '\n';      // {"one":[1],"two":[1,2]}
308     std::cout << j_nested_array << '\n';       // [[[1],"one"],[1,2],"two"]
309 }
310 
311 void json_move_constructor()
312 {
313     // create a JSON value
314     json a = 23;
315 
316     // move contents of a to b
317     json b(std::move(a));
318 
319     // serialize the JSON arrays
320     std::cout << a << '\n';    // null
321     std::cout << b << '\n';    // 23
322 }
323 
324 void json_copy_assignment()
325 {
326     // create JSON values
327     json a = 23;
328     json b = 42;
329 
330     // copy-assign a to b
331     b = a;
332 
333     // serialize the JSON arrays
334     std::cout << a << '\n';    // 23
335     std::cout << b << '\n';    // 23
336 }
337 
338 void json_nullptr_t()
339 {
340     // implicitly create a JSON null value
341     json j1;
342 
343     // explicitly create a JSON null value
344     json j2(nullptr);
345 
346     // serialize the JSON null value
347     std::cout << j1 << '\n' << j2 << '\n';   // null    null s
348 }
349 
350 void json_basic_type_value()
351 {
352     // create a JSON object with different entry types
353     json j =
354     {
355         {"integer", 1},
356         {"floating", 42.23},
357         {"string", "hello world"},
358         {"boolean", true},
359         {"object", {{"key1", 1}, {"key2", 2}}},
360         {"array", {1, 2, 3}}
361     };
362 
363     // access existing values
364     int v_integer = j.value("integer", 0);
365     double v_floating = j.value("floating", 47.11);
366 
367     // access nonexisting values and rely on default value
368     std::string v_string = j.value("nonexisting", "oops");
369     bool v_boolean = j.value("nonexisting", false);
370 
371     // output values
372     std::cout << std::boolalpha << "\n";     // 1
373     std::cout << v_integer << "\n";          // 1
374     std::cout << v_floating << "\n";         // 42.23
375     std::cout << v_string << "\n";           // oops
376     std::cout << v_boolean << "\n";          // false
377 }
378 
379 void json_basic_value_t()
380 {
381     // create the different JSON values with default values
382     json j_null(json::value_t::null);
383     json j_boolean(json::value_t::boolean);
384     json j_number_integer(json::value_t::number_integer);
385     json j_number_float(json::value_t::number_float);
386     json j_object(json::value_t::object);
387     json j_array(json::value_t::array);
388     json j_string(json::value_t::string);
389 
390     // serialize the JSON values
391     std::cout << j_null << '\n';            // null
392     std::cout << j_boolean << '\n';         // false
393     std::cout << j_number_integer << '\n';  // 0
394     std::cout << j_number_float << '\n';    // 0.0
395     std::cout << j_object << '\n';          // {}
396     std::cout << j_array << '\n';           // []
397     std::cout << j_string << '\n';          // ""
398 }
399 
400 void json_iterator()
401 {
402     // create an array value
403     json array = { 1, 2, 3, 4, 5 };
404 
405     // get am iterator to the first element
406     json::iterator itor = array.begin();
407 
408     // serialize the element that the iterator points to
409     std::cout << *itor << '\n';    // 1
410 
411     // create an array using push_back
412     json j;
413     j.push_back("foo");
414     j.push_back(1);
415     j.push_back(true);
416 
417     // also use emplace_back
418     j.emplace_back(1.78);
419 
420     // iterate the array
421     for (json::iterator it = j.begin(); it != j.end(); ++it)
422     {
423         std::cout << *it << '\n';
424     }
425 
426     // range-based for
427     for (auto& element : j) 
428     {
429         std::cout << element << '\n';
430     }
431 
432     // getter/setter
433     const auto tmp = j[0].get<std::string>();
434     j[1] = 42;
435     bool foo = j.at(2);
436 
437     // comparison
438     j == "[\"foo\", 42, true]"_json;  // true
439 
440     // other stuff
441     j.size();     // 3 entries
442     j.empty();    // false
443     j.type();     // json::value_t::array
444     j.clear();    // the array is empty again
445 
446     // convenience type checkers
447     j.is_null();
448     j.is_boolean();
449     j.is_number();
450     j.is_object();
451     j.is_array();
452     j.is_string();
453 
454     // create an object
455     json o;
456     o["foo"] = 23;
457     o["bar"] = false;
458     o["baz"] = 3.141;
459 
460     // also use emplace
461     o.emplace("weather", "sunny");
462 
463     // special iterator member functions for objects
464     for (json::iterator it = o.begin(); it != o.end(); ++it) 
465     {
466         std::cout << it.key() << " : " << it.value() << "\n";
467     }
468 
469     // the same code as range for
470     for (auto& el : o.items()) 
471     {
472         std::cout << el.key() << " : " << el.value() << "\n";
473     }
474 
475 #if 0
476     // even easier with structured bindings (C++17)
477     for (auto& [key, value] : o.items()) 
478     {
479         std::cout << key << " : " << value << "\n";
480     }
481 #endif
482 
483     // find an entry
484     if (o.find("foo") != o.end()) 
485     {
486         // there is an entry with key "foo"
487     }
488 
489     // or simpler using count()
490     int foo_present = o.count("foo"); // 1
491     int fob_present = o.count("fob"); // 0
492 
493     // delete an entry
494     o.erase("foo");
495 }
496 
497 void json_serialization_deserialization()
498 {
499     // create object from string literal
500     json j = "{ \"happy\": true, \"pi\": 3.141 }"_json;
501 
502     // or even nicer with a raw string literal
503     auto j2 = R"(
504     {
505         "man": false,
506         "love": 1314
507      })"_json;
508 
509     std::string s = j.dump();
510     std::cout << s << std::endl;
511     std::cout << j.dump(4) << std::endl;
512 
513     std::string s2 = j2.dump();
514     std::cout << s2 << std::endl;
515     std::cout << j2.dump(4) << std::endl;
516 
517     auto j3 = json::parse("{ \"happy\": false, \"pi\": 3.141 }");
518     std::cout << j3.dump() << std::endl;
519 
520     // store a string in a JSON value
521     json j_string = "this is a string";
522 
523     // retrieve the string value
524     auto cpp_string = j_string.get<std::string>();
525     // retrieve the string value (alternative when an variable already exists)
526     std::string cpp_string2;
527     j_string.get_to(cpp_string2);
528 
529     // retrieve the serialized value (explicit JSON serialization)
530     std::string serialized_string = j_string.dump();
531 
532     // output of original string
533     std::cout << cpp_string << " == " << cpp_string2 << " == " << j_string.get<std::string>() << '\n';
534     // output of serialized value
535     std::cout << j_string << " == " << serialized_string << std::endl;
536 }
537 
538 void json_read_write_file()
539 {
540     std::string json_read_path = "F:/study_nlohmanjson/nlohmannjson/nlohmannjson/json_demo.json";
541     std::string json_write_path = "F:/study_nlohmanjson/nlohmannjson/nlohmannjson/json_write.json";
542 
543     std::ifstream ifile(json_read_path);
544     json j;
545     ifile >> j;
546 
547     std::cout << j.dump(4) << std::endl;
548 
549     std::ofstream ofile(json_write_path);
550     ofile << std::setw(4) << j << std::endl;
551 }
552 
553 namespace ns_person
554 {
555     // a simple struct to model a person
556     struct person 
557     {
558         std::string name;
559         std::string address;
560         int age;
561     };
562 
563     void to_json(json& j, const person& p) 
564     {
565         j = json{ {"name", p.name}, {"address", p.address}, {"age", p.age} };
566     }
567 
568     void from_json(const json& j, person& p)
569     {
570         j.at("name").get_to(p.name);
571         j.at("address").get_to(p.address);
572         j.at("age").get_to(p.age);
573     }
574 }
575 
576 void json_custom_types_conversions()
577 {
578     ns_person::person p = { "Ned Flanders", "744 Evergreen Terrace", 60 };
579 
580     // convert to JSON: copy each value into the JSON object
581     json j;
582     j["name"] = p.name;
583     j["address"] = p.address;
584     j["age"] = p.age;
585 
586     // convert from JSON: copy each value from the JSON object
587     ns_person::person p2{
588         j["name"].get<std::string>(),
589         j["address"].get<std::string>(),
590         j["age"].get<int>()
591     };
592 
593     // create a person
594     ns_person::person p3{ "Ned Flanders", "744 Evergreen Terrace", 60 };
595 
596     // conversion: person -> json
597     json j3 = p3;
598 
599     std::cout << j3 << std::endl;
600     // {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}
601 
602     // conversion: json -> person
603     auto p4 = j3.get<ns_person::person>();
604 }
605 
606 int main()
607 {
608     // [1] json as first-class data type
609     // json_object();
610 
611     // [2] json array
612     // json_arry();
613 
614     // [3] json_object_at_key
615     // json_object_at_key();
616 
617     // [4] json_array_at_index
618     // json_array_at_index();
619 
620     // [5] json_at_pointer
621     // json_at_pointer();
622 
623     // [6] json_compare
624     // json_compare();
625 
626     // [7] json_list_init
627     // json_list_init();
628 
629     // [8] json_move_constructor
630     // json_move_constructor();
631 
632     // [9] json_copy_assignment
633     // json_copy_assignment();
634 
635     // [10] json_nullptr_t
636     // json_nullptr_t();
637 
638     // [11] json_basic_type_value
639     // json_basic_type_value();
640 
641     // [12] json_basic_value_t
642     // json_basic_value_t();
643 
644     // [13] json_iterator
645     // json_iterator();
646 
647     // [14] serialization/deserialization
648     // json_serialization_deserialization();
649 
650     // [15] json_read_write_file
651     // json_read_write_file();
652 
653     // [16] json_custom_types_conversions
654     json_custom_types_conversions();
655 
656     system("pause");
657 }

good good study, day day up.

顺序 选择 循环 总结

posted @ 2020-02-16 23:45  kaizenly  阅读(6458)  评论(0编辑  收藏  举报
打赏