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.
顺序 选择 循环 总结