C++ JSON ライブラリ jsoncpp 新 API の使用法 (CharReaderBuilder / StreamWriterBuilder)
あなたはこの記事を見ているので、Jsonが何であるかを知っている必要があります、Jsonを解析するための多くのオープンソースライブラリがあり、最近の仕事は、Jsonのパースを使用する必要があります、研究はjsoncppは非常に便利に使用することがわかった、インターネットを使用する多くの方法もあります、これまでの基本APIを見つけることができます使用の比較的古い方法、コンパイラはいくつかのAPIの使用が放棄されて思い出される いくつかのAPIが非推奨されていると、いくつかのコンパイラが直接エラー報告することだろう。
新しくシンプルなjsonライブラリを見つけたので、星をたくさんつけて、こちらをお勧めします nlohmann/json .
JSONCPPは、人間が理解しやすく、機械が解析しやすい軽量なデータ交換フォーマットであるJSON文字列の生成とパース用のC++実装です。jsoncppは、Githubからダウンロードすることができます。 https://github.com/open-source-parsers/jsoncpp .
使用方法
スタティック/ダイナミックライブラリの使用
公式には、プロジェクトの説明にあるように、コンパイルにはNinjaを使うことが推奨されています。もちろん、より一般的なcmakeを使用してコンパイルすることも可能です。
mkdir -p build/debug
cd build/debug
cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=ON -DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" ... /...
make
生成されたスタティック/ダイナミックライブラリファイルのディレクトリは
build/debug/src/lib_json/
使用するには、プロジェクトにincludeヘッダファイルを追加してリンクします
-ljsoncpp
パラメータでリンクライブラリーを指定します。
ソースファイルの使用
静的なライブラリを使うより、ソースファイルを直接使う方が便利な気がします。
プロジェクトディレクトリで直接実行する
python amalgamate.py
コマンドを追加します。
dist
ディレクトリに、2つのヘッダーファイルと1つのソースファイルが生成されます。
json-forwards.h
は、その
json.h
と
jsoncpp.cpp
. jsoncppのソースコードは4、5千行しかないので、プロジェクト内の他のコードと一緒にjsconcpp.cppで直接コンパイルした方が簡単です。
新しいAPI
ここにデモ用のランダムなJsonデータがあります。以下のJson文字列は配列とインラインのJson文字列を含んでいますが、これは一般的によくあることですよね?
{
"Name": "Liming",
"Age": 26,
"Language": ["C++", "Java"],
"E-mail": {
"Netease": "[email protected]",
"Hotmail": "[email protected]"
}
}
#include
#include "json/json.h"
std::string createJson()
{
std::string jsonStr;
Json::Value root, lang, mail;
Json::StreamWriterBuilder writerBuilder;
std::ostringstream os;
root["Name"] = "Liming";
root["Age"] = 26;
lang[0] = "C++";
lang[1] = "Java";
root["Language"] = lang;
mail["Netease"] = "[email protected]";
mail["Hotmail"] = "[email protected]";
root["E-mail"] = mail;
std::unique_ptr<Json::StreamWriter> jsonWriter(writerBuilder.newStreamWriter());
jsonWriter->write(root, &os);
jsonStr = os.str();
std::cout << "Json:\n" << jsonStr << std::endl;
return jsonStr;
}
Json文字列を生成する
Json:
{
"Age" : 26,
"E-mail" :
{
"Hotmail" : "[email protected]",
"Netease" : "[email protected]"
},
"Language" :
[
"C++",
"Java"
],
"Name" : "Liming"
}
この関数を呼び出すと、次のように出力されます。
bool parseJson(const std::string &info)
{
if (info.empty())
return false;
bool res;
JSONCPP_STRING errs;
Json::Value root, lang, mail;
Json::CharReaderBuilder readerBuilder;
std::unique_ptr<Json::CharReader> const jsonReader(readerBuilder.newCharReader());
res = jsonReader->parse(info.c_str(), info.c_str()+info.length(), &root, &errs);
if (!res || !errs.empty()) {
std::cout << "parseJson err. " << errs << std::endl;
}
std::cout << "Name: " << root["Name"].asString() << std::endl;
std::cout << "Age: " << root["Age"].asInt() << std::endl;
lang = root["Language"];
std::cout << "Language: ";
for (int i = 0; i < lang.size(); ++i) {
std::cout << lang[i] << " ";
}
std::cout << std::endl;
mail = root["E-mail"];
std::cout << "Netease: " << mail["Netease"].asString() << std::endl;
std::cout << "Hotmail: " << mail["Hotmail"].asString() << std::endl;
return true;
}
Json文字列のパース
Jsonを解析するための前提条件は、Jsonの文字列にどのようなデータが含まれているかが分かっていることです。上記の関数で生成されたJson文字列に対して、以下の関数を使ってデータをパースします。
Name: Liming
Age: 26
Language: "C++" "Java"
Netease: [email protected]
Hotmail: [email protected]
前の関数の戻り値を入力パラメータとして、main関数内からこの関数を呼び出すと、次のような出力が得られます。
Json::Value root, ex;
Json::FastWriter writer;
root["Name"] = "Lucy";
root["age"] = 20;
ex[0] = "ABC";
ex[1] = "DEF";
root["exinfo"] = ex;
string json = writer.write(root);
Json::Reader reader;
Json::Value root;
const char *jsonStr = "{\"Name\":\"Lucy\",\"Age\":20}";
if (!reader.parse(jsonStr, jsonStr + strlen(jsonStr), root)) {
std::cout << "json parse failed\n";
return 1;
}
std::string name = root["Name"].asString();
int age = root["Age"].asInt();
旧API
Webでの検索はほとんどが古いAPIなので、テストを整理するのが面倒なのですが、おそらくこちら側のような感じだと思います。上の新しいAPIと同じようにネストしています。
Jsonを生成する
warning: 'Reader' is deprecated: Use CharReader and CharReaderBuilder instead [-Wdeprecated-declarations]
warning: 'FastWriter' is deprecated: Use StreamWriterBuilder instead [-Wdeprecated-declarations]
Jsonのパース
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#elif defined(_MSC_VER)
#pragma warning(disable : 4996)
#endif
旧APIを使用するコンパイラには、以下のようなアラートが表示され、あるコンパイラは警告を、あるコンパイラはエラーを報告し、そして
Json::Value
古いAPIにこだわるなら、このコードをファイルのヘッダーに追加すればいい。
root["Name"]
概要
を配置することが可能です。
.asString()
を Json 構造体として使用し、ネストしたり配列のように使用したりすることができ、必要なときに適切な型に変換することができます。
例えば
私たちはすでに、以下のことを知っています。
string
を使用して文字列に置き換えることができる文字列を格納します。
root["Language"]
から
Json::Value
タイプになります。
を知っていること
root["E-mail"]
これは
Json::Value
は配列なので、配列と同じように添え字を使って取得することができます。
を知っていること
root
これは
Json::Value
は内部でネストしたjsonなので
// Convert types
Int asInt() const;
UInt asUInt() const;
Int64 asInt64() const;
UInt64 asUInt64() const;
LargestInt asLargestInt() const;
LargestUInt asLargestUInt() const;
float asFloat() const;
double asDouble() const;
bool asBool() const;
// Detect the type
bool isNull() const;
bool isBool() const;
bool isInt() const;
bool isInt64() const;
bool isUInt() const;
bool isUInt64() const;
bool isIntegral() const;
bool isDouble() const;
bool isNumeric() const;
bool isString() const;
bool isArray() const;
bool isObject() const;
の構造を持つ。
Json::Value
その他のメンバー関数は
// Convert types
Int asInt() const;
UInt asUInt() const;
Int64 asInt64() const;
UInt64 asUInt64() const;
LargestInt asLargestInt() const;
LargestUInt asLargestUInt() const;
float asFloat() const;
double asDouble() const;
bool asBool() const;
// Detect the type
bool isNull() const;
bool isBool() const;
bool isInt() const;
bool isInt64() const;
bool isUInt() const;
bool isUInt64() const;
bool isIntegral() const;
bool isDouble() const;
bool isNumeric() const;
bool isString() const;
bool isArray() const;
bool isObject() const;
残りは自分でソースコードを確認してください。
間違いがあればご指摘ください、ありがとうございます〜。
関連
-
error: '&' トークンの前にイニシャライザーがあるはずです。
-
gcc/g++ コンパイル時のエラー解析で期待される型指定子の前に
-
error: label 'xxxxxxx' [-fpermissive] にジャンプします。
-
C++ [エラー] 'std::string {aka std::basic_string<char>}' を 'char*' に変換できないエラー
-
警告を表示します。ISO C++は文字列定数を'char*'に変換することを禁じています[-Write-strings]。
-
munmap_chunk():不正なポインタとSegmentation faultのバグを解決。
-
C++ Error no matching function for call to 'std::basic_ofstream<char>::basic_ofstream(std::string&)
-
抽象クラス型 "my class "のオブジェクトは使用できません 解決方法
-
c++ 11 random ライブラリの簡単な使い方
-
"name.bat "は、内部または外部のコマンド、操作可能なプログラムまたはバッチファイルとして認識されません。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
C++11での移動セマンティクス(std::move)と完全な前進(std::forward)。
-
エラー: 'xxx' は事前宣言と C++ ヘッダーファイルが互いに含まれているため、型名になりません。
-
C++コンパイルエラー:||error: ld returned 1 exit status|.
-
void* から char* への無効な変換」および「文字列定数から 'char*' への非推奨の変換」を解決 "
-
C++] error: 'const xxx' を 'this' 引数として渡すと修飾子が破棄される [-fpermissive] [C++] error: 'const xxx' を 'this' 引数として渡すと修飾子が破棄される。
-
C++のコンパイルエラーで修飾子が破棄される [-fpermissive] 。
-
C++: エラー C2228: '.str' の左側にはクラス/構造体/結合が必要
-
警告: この関数では 'p' が初期化されていない状態で使用されることがあります。
-
"エラー:不完全なクラス型へのポインタは許可されません。"の前方宣言。
-
C++ inet_pton, inet_ntop 関数