iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 23
1
Software Development

C++ 30天屠龍記系列 第 23

C++ 30天屠龍記(第23天): 今天的主題是JSON

前言

我們今天就說一下JSON,JSON全稱是Javascript Object Notation,簡而言之就是Javascript物件式編程的表示式。在Javascript中可以取代不少在C++裡才有的不同資料結構。

https://ithelp.ithome.com.tw/upload/images/20191002/20120557c2O2F5ZkWt.png

我們今天講他的原因有三個

優勢

  1. 他可以做出非常強大的Map,強大到可以模擬物件式編程,對理解基本概念很有幫助
  2. 他是C++當中最簡單的離線儲存格式(第二簡單是SQLite)
  3. JSON是網絡編程資料傳輸基本格式,在C++20將加入網絡編程庫的時刻,學會他很有必要

環境setup

CmakeLists.txt

cmake_minimum_required(VERSION 3.1..3.15)

project(helloJSON)

# Add Library:
		find_package(fmt)
		find_package(nlohmann_json)
# Build:
		add_executable(main src/main.cpp)
# Link Library:
		target_link_libraries(main fmt::fmt)
	  target_link_libraries(main nlohmann_json::nlohmann_json)
# C++ Version:
		target_compile_features(main PUBLIC cxx_std_17)

用你的package manager 安裝 nlohmann json,不同的包管理器有不同的名字,可以用那個包管理器的 Search 和 info功能去尋找相應的版本,nlohmann_json現在是第三版本

加入新的數值

main.cpp

#include "fmt/format.h" //這東西如果你不喜歡可以換成iostream
#include <string>
#include "nlohmann/json.hpp"

using json = nlohmann::json; //你可以改其他名字,例如JSON這樣
using namespace fmt;
using namespace std;

int main(){
	json person;
	person["age"] = 32;
	person["name"] = "Amanda"
	person["gender"] = "F";
	person["contact"]["address"] = "Taiwan";
	person["contact"]["phone"] = "24331276";
	person["weight"] = 47.6;
	person["happy"] = true;
	
	print("{}\n",person.dump(4));

}

輸出

{
    "age": 32,
    "contact": {
        "address": "Taiwan",
        "phone": "24331276"
    },
    "gender": "F",
    "happy": true,
    "name": "Amanda",
    "weight": 47.6
}

直接創造一個JSON

以上的語法主要是用來更改/加入JSON數值的,如果我們需要建立一個JSON物件的話,可以用C++的方法

auto Amanda = R"(
	{
    "age": 32,
    "contact": {
        "address": "Taiwan",
        "phone no:": "24331276"
    },
    "gender": "F",
    "happy": true,
    "name": "Amanda",
    "weight": 47.6
	}
)"_json;

刪除數值

Amanda.erase("weight");

在Array/Vector中的JSON 資料

你可以先建立一個JSON Array

auto json_array = json::array();

auto person1 = R"(
	{
		"age":12,
		"name":"Tony"
	}
)"_json;

json_array.emplace_back(person1);
json_array.emplace_back(person1);
json_array.emplace_back(person1);

也可以建立一個普通Vector,普通vector比較快但只能在C++使用

json temptype;
vector<decltype(temptype)> vector_json;
auto person1 = R"
	{
		"age":12,
		"name":"Tony"
	}
"_json;
vector_json.emplace_back(person1);
vector_json.emplace_back(person1);
vector_json.emplace_back(person1);
  • decltype通常在使用外部Libraries的時候使用,因為我們根本不知道外部Library 資料類型的名字是什麼,而vector等STL類型(Day7-9,14的內容)卻要求我們提供類型,所以唯有這樣了。

轉換任何STL資料結構為JSON

vector<int> c_vector {1, 2, 3, 4}; //可以是Deque或者List/Map
json jsonObject();

小結(1)

你可以嘗試用不同的方法建立一個JSON的結構,例如用電話的特性,或者單車,甚至是小狗,咖啡店等等。

2. 儲存JSON到硬碟/從硬碟讀取JSON

假設我們的Object依然是Amanda

#include<fstream>
auto Amanda = R"(
	{
    "age": 32,
    "contact": {
        "address": "Taiwan",
        "phone no:": "24331276"
    },
    "gender": "F",
    "happy": true,
    "name": "Amanda",
    "weight": 47.6
	}
)"_json;
//寫到JSON檔案中
ofstream o("amanda.json");
o << setw(4) << Amanda << endl;
//讀取JSON檔案
ifstream i("amanda.json");
json amanda2;
amanda2 << i;

print("{}\n",amanda);
print("{}\n",amanda2);
//大家可以比比看是否一樣,也可以打開Amanda檔案看看

3. 物件式編程的功能

你們可以很容易的用JSON實現一個物件的功能,以下是一個例子,例如我要設計一隻狗狗

#include <vector>
#include <string>
#include "fmt/format.h" //這東西如果你不喜歡可以換成iostream
#include "nlohmann/json.hpp"
#include<map>
using json = nlohmann::json; //你可以改其他名字,例如JSON這樣
using namespace fmt;
using namespace std;

auto Dog = [](auto name, auto age, auto gender){
	json dog;
	dog["name"] = name;
	dog["age"] = age;
	dog["gender"] = gender;
	return dog;
};

auto bark = [](auto& dog){
	print("WOO");
};

auto angry = [](auto& dog){
	print("WOO Wa We");
};

auto info = [](auto& dog){
	print("name:{} age:{} gender:{}",name,age,gender);
};

map<string,decltype(bark)> act;
act["bark"] = bark;
act["angry"] = angry;
act["info"] = info;
auto DogAct = [](auto dog,string action){
	act[action](dog);
};

int main(){
	auto dog2 = Dog("Winnie",12,"F");
	DogAct(dog2,bark);
	DogAct(dog2,info);
	return 0;
}

這只是一個大概的樣子,畢竟JSON最擅長的是他的可變性,容易儲存,和網絡編程應用廣泛,至於速度和其他的其實需要C++ Class 啦。

因為C++ Class比較不可改變,大家可以用這個東西練習以下怎麼設計一個易用的Data Object。


上一篇
Day 22 - Cmake的編譯與專案流程
下一篇
C++ 30天屠龍記(第24天): C++模板
系列文
C++ 30天屠龍記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言