[C言語]jansson.hでシリアライズ化と逆シリアライズ化する方法

C言語/C++

以前にC言語でJsonファイルを利用する機会があり、その時のメモ書きです。
以下では、Jsonファイルをシリアライズ化と逆シリアライズ化する方法を確認します。

janssonとは?

・C言語で使用できるJSONファイル読み込み用ライブラリのことです

スポンサーリンク

はじめに

以下で紹介する内容はUbuntuでgccを使った場合の内容です。
まずはインストール方法です。

$sudo apt-get install -y libjansson-dev

利用するときには、インクルードします。

#include <jansson.h>
Checkポイント

libjanssonを使用する場合には、ビルド時にリンクオプション「-ljansson」を使用する必要があります。

gcc sample.c -ljansson

Jsonファイルサンプル

利用するJsonファイルのサンプルです。ファイル名はconfig.jsonとします。

{
    "fileInfo": 
    {
        "file-name":"abcdefg.txt",
        "No":1,
        "ver":1.2
    },
    "array-section": 
    [
        {
            "No":1345
        },
        {
            "No":7890
        },
        {
            "No":9999
        }
    ]
}

Jsonファイルにシリアライズ化する方法

まずは、Jsonファイルをシリアライズ化する方法です。(Jsonファイルの作成)
サンプルファイルと同じ内容のJsonファイルを作成してみます。

#include <jansson.h>
#include <string.h>

int main(int argc, char* argv[]) {
	
	//ルート要素の作成
	json_t* json_root = json_object();

	//json要素をセット
	json_t* json_fileinfo = json_object();
	if (json_fileinfo) {
		//filename
		json_object_set(json_fileinfo, "filename", json_string("abcdefg.txt"));
		//number
		json_object_set(json_fileinfo, "number", json_integer((json_int_t)1));
		//ver
		json_object_set(json_fileinfo, "ver", json_real((double)1.2));
		//ルートにセット
		json_object_set(json_root, "fileInfo", json_fileinfo);
		json_decref(json_fileinfo);
	}
	//array-section
	json_t* json_array_section = json_array();
	if (json_array_section){
		int array_no[] = { 1345, 7890, 9999 };
		for (int i = 0; i < 3; i++) {
			json_t* section = json_object();
			json_object_set(section, "No", json_integer((json_int_t)array_no[i]));
			json_array_append(json_array_section, section);
		}
		json_object_set(json_root, "array-section", json_array_section);
		json_decref(json_array_section);
	}
	printf("%s\n", json_dumps(json_root, json_object_size(json_root)));
	// dump
	json_decref(json_root);
}

シリアライズ化の実行結果

補足

Jsonファイルに出力する方法

#include <stdio.h>

FILE* fp;
fp = fopen("configa.json", "w");
fprintf(fp, "%s", json_dumps(json_root, json_object_size(json_root)));
fclose(fp);

Jsonファイルを逆シリアライズ化する方法

Jsonファイルを逆シリアライズ化する方法です。(Jsonファイルを読み込み)
まずは、Jsonファイルを読み込む部分から

int main() {
    json_t* json_root;
    json_error_t json_error;

    json_root = json_load_file("config.json",  0, &json_error);
    if ( !json_root ) {
        fprintf(stderr, "%s", json_error.text);
        exit(-1);
    }
    /*処理*/
    /*利用後に解放*/
    json_decref(json_root);
}
重要①

jsonファイルを読み込む方法です。
json_t* json_load_file(const char* path, size_t flags, json_error_t* error);
エラーの場合、NULLを返却されるので利用前にチェックしましょう。

重要②

利用後は、オブジェクトの解放を忘れずに行う。
void json_decref(json_t* json);

次は、逆シリアライズ化のサンプルコードです。

#include <jansson.h>
#include <string.h>


typedef struct {
	const char* filename;
	int number;
	double ver;
	int array[3];
} FileInfo;

int main(int argc, char* argv[]) {

	if (argc != 2) {
		printf("json file not set");
		exit(1);
	}
	
	//Jsonファイル読み込み
	json_t* json_root;
	json_error_t json_error;
	json_root = json_load_file(argv[1], 0, &json_error);
	if (!json_root) {
		fprintf(stderr, "%s", json_error.text);
		exit(-1);
	}

	//jsonファイルオブジェクトを取得
	FileInfo info;
	json_t* json_orign;
	json_orign = json_object_get(json_root, "fileInfo");
	if (json_orign) {
		json_t* json_value;
		//file-name
		json_value = json_object_get(json_orign, "file-name");
		info.filename = json_string_value(json_value);
		//No
		json_value = json_object_get(json_orign, "No");
		info.number = json_integer_value(json_value);
		//ver
		json_value = json_object_get(json_orign, "ver");
		info.ver = json_real_value(json_value);
		//dump
		json_decref(json_value);
		printf("filename:%s\nnumber:%d\nver:%f\n", info.filename, info.number,info.ver);
	}
	json_orign = json_object_get(json_root, "array-section");
	if (json_orign) {
		//array_section
		json_t* json_value;
		json_t* item;
		for (size_t i = 0; ; i++) {
			item = json_array_get(json_orign, i);
			if (!item) {
				break;
			}
			json_value = json_object_get(item, "No");
			if (json_value) {
				info.array[i] = json_integer_value(json_value);
				printf("No:%d\n", info.array[i]);
			}
			json_decref(json_value);
		}
	}
	// dump
	json_decref(json_root);
}
Point

objectからkeyに対応する値を取得する。
json* json_object_get(const json_t* object, const char* key);
キーが見つからずエラーの場合にはNULLが返却されるためチェックが必要な場合には忘れずに

各型のオブジェクトの取得方法

それぞれの型に応じた取得方法は以下です。

int型の値を取得

json_int_t json_integer_value(const json_t* integer);
jsonが整数でない場合には0が返却されます。

文字列型の値を取得

const char* json_string_value(const json_t* string);
jsonが文字列でない場合にはNULLが返却されます。

【補足】戻り値は読み取り専用であるが、変更できる状態で取得するためはどうするのか?

char buf[256];
json_value = json_object_get(json_orign, "file-name");
strcpy(buf, json_string_value(json_value));
double型の値を取得

double json_real_value(const json_t* real);
jsonが実数出ない場合には0.0が返却されます。

array型を取得

json_t* json_array_get(const json_t* array, size_t index);
引数arrayがNULLまたは引数indexが範囲外の場合にはNULLが返却されます。

逆シリアライズ化の実行結果

参考

以下が今回参考にしたJanssonドキュメントです。

API Reference — Jansson 2.8 documentation
この記事を書いた人
プロフィール

サイト管理人
プログラマーを6年程しています。
プログラミングの情報やPC情報などを中心にアップしています。
得意言語:C言語/C++,Python,C#

夢犬をフォローする
スポンサーリンク
C言語/C++
夢犬をフォローする
タイトルとURLをコピーしました