tar zxvf jansson-2.13.1.tar.gz |
./configure --prefix=/usr --disable-static && make |
root ユーザーになって以下を実行します。
sudo make install |
#include <jansson.h> |
ライブラリのリンクはコンパイル時に以下のように指定します。
-ljansson |
それでは以下のJSONファイルを読み込んでみます。
このサンプルでは全部の要素ではなく、読みたい項目のみを抜粋して取得します。
ファイル:json.txt
{
"hostname": "127.0.0.1",
"sendPort": 80,
"Description":
"Sequential pattern",
"DependOnSequentialEvent":
{ "environmentType": "PHU", "valPercent": 83.700, "isScript": true, "Location": { "state1": 98, "state2": 44493, "state3": 298 }, "pict":
"ES-JJ0938", "serialNo": 31984, "currentEvent": true, "alive": "yes", "picturesNumber": 2
},
"eventState":
"active",
"eventType":
"DependOnSequentialEvent",
"cdID": 1,
"netPonds": 1,
"dateTime": "2020-10-24 19:13:49" } |
main.c
#include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/stat.h> #include <fcntl.h> #include <jansson.h>
int parseJson(const char *buffer,
size_t buflen) {
// JSONオブジェクトを入れる変数
json_error_t error;
json_t* root;
json_t* obj;
const char *str;
double dValue;
int iValue;
// JSON全体バッファを読み込む
root = json_loadb(buffer, buflen, 0, &error);
if ( root == NULL )
{ printf("[ERR]json load
FAILED\n"); return 1;
}
printf("------------------------------------\n");
obj = json_object_get(root, "dateTime");
if(json_is_string(obj))
{ str = json_string_value(obj); printf("dateTime: %s\n",
str);
}
obj = json_object_get(root, "eventType");
if(json_is_string(obj))
{ str = json_string_value(obj);
printf("eventType:
%s\n", str);
}
obj = json_object_get(root, "DependOnSequentialEvent");
if(json_is_object(obj))
{ json_t* obj2;
obj2 = json_object_get(obj,
"valPercent"); if(json_is_real(obj2)) { dValue = json_real_value(obj2); printf("valPercent(double):
%f\n", dValue); } else if(json_is_integer(obj2)) { iValue =
json_integer_value(obj2); printf("valPercent(int):
%d\n", iValue); }
obj2 = json_object_get(obj,
"alive"); if(json_is_string(obj2)) { str = json_string_value(obj2); printf("alive: %s\n",
str); }
obj2 = json_object_get(obj,
"isScript"); if(json_is_true(obj2)) { printf("isScript:
true\n"); } if(json_is_false(obj2)) { printf("isScript:
false\n"); }
}
printf("------------------------------------\n"); }
int main(){
char block[65535];
char *file = "json.txt";
int fd = open(file, O_RDONLY);
if (fd < 0) { // open 失敗 fprintf(stderr, "open(%s)
errror:%d\n", file, fd); return -1;
}
int size = read(fd, block, sizeof(block));
if (size < 0) { fprintf(stderr, "read()
errror:%d\n", fd); close(fd); return -1;
}
close(fd);
parseJson((const char*)block, size); } |
makefile
EXEC = jsontest OBJS = main.o \
all : clean $(EXEC)
clean : -rm
-f $(EXEC) *.elf *.gdb *.o *~
$(EXEC): $(OBJS) gcc -g -O0 -o $@ $(OBJS) -lm -ljansson
%.o: %.c gcc
-c -g3 -O0 -o $@ $<
|
実行結果
$ ./jsontest ------------------------------------ dateTime: 2020-10-24 19:13:49 eventType: DependOnSequentialEvent valPercent(double): 83.700000 alive: yes isScript: true ------------------------------------ |
まずJSON全体をオブジェクトに取得します(json_loadb関数)
ここではバッファ指定のjson_loadb関数を使用しています。JSON形式でなければエラーとなります。これで全体のオブジェクトを取得します。
各要素は名前指定で対象オブジェクトに対してのオブジェクトとして取得します(json_object_get関数)。
オブジェクト=json_object_get(対象オブジェクト, 文字列);
取得したオブジェクトを判断します(is関数)。
例えば数値で取得する場合は
json_is_integer(オブジェクト)
でtrue/falseが得られます。この判断は必須ではありませんが、この判断が間違っていると次の取得でエラーとなります。
取得します。
例えば上記の数値の場合であれば
json_integer_value(オブジェクト)
で値が得られます。
Bool型(true/false)を取得する場合は
json_is_true関数, json_is_false関数で判断するのが良いでしょう。
下の階層を取得する場合はjson_object_get関数で取得したオブジェクトが下の階層となります。ソースを見ればわかると思います。
また、各階層内で取得する際は、文字列指定なので、上から取得しなければならないわけではありません。ソース上でも敢えて取得順はバラバラにしています。
実数(double)を取得するのはjson_real_value関数を使用しますが、この関数では整数表記は取得できません。
事前に、json_is_integer(整数判断)、json_is_real(実数判断)をするのが望ましいと思います。
ファイル:json.txt
{
"hostname": "127.0.0.1",
"sendPort": 80,
"Description":
"Sequential pattern",
"DependOnSequentialEvent":
{ "environmentType": "PHU", "valPercent": 83.700, "isScript": true, "Location": [ { "state1": 98, "state2": 44493, "state3": 298 }, { "state1": 198, "state2": 144493, "state3": 1298 }, { "state1": 298, "state2": 244493, "state3": 2298 } ], "pict":
"ES-JJ0938", "serialNo": 31984, "currentEvent": true, "alive": "yes", "picturesNumber": 2
},
"eventState":
"active",
"eventType":
"DependOnSequentialEvent",
"cdID": 1,
"netPonds": 1,
"dateTime": "2020-10-24 19:13:49" } |
main.c
#include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/stat.h> #include <fcntl.h> #include <jansson.h>
int parseJson(const char *buffer,
size_t buflen) {
// JSONオブジェクトを入れる変数
json_error_t error;
json_t* root;
json_t* obj;
const char *str;
double dValue;
int iValue;
// JSON全体バッファを読み込む
root = json_loadb(buffer, buflen, 0, &error);
if ( root == NULL )
{ printf("[ERR]json load FAILED\n"); return 1;
}
printf("------------------------------------\n");
obj = json_object_get(root, "dateTime");
if(json_is_string(obj))
{ str = json_string_value(obj); printf("dateTime: %s\n",
str);
}
obj = json_object_get(root, "eventType");
if(json_is_string(obj))
{ str = json_string_value(obj); printf("eventType: %s\n",
str);
}
obj = json_object_get(root, "DependOnSequentialEvent");
if(json_is_object(obj))
{ json_t* obj2;
obj2 = json_object_get(obj,
"valPercent"); if(json_is_real(obj2)) { dValue = json_real_value(obj2); printf("valPercent(double):
%f\n", dValue); } else if(json_is_integer(obj2)) { iValue =
json_integer_value(obj2); printf("valPercent(int):
%d\n", iValue); }
obj2 = json_object_get(obj,
"alive"); if(json_is_string(obj2)) { str = json_string_value(obj2); printf("alive: %s\n",
str); }
obj2 = json_object_get(obj,
"isScript"); if(json_is_true(obj2)) { printf("isScript:
true\n"); } if(json_is_false(obj2)) { printf("isScript:
false\n"); }
obj2 = json_object_get(obj,
"Location"); if(json_is_array(obj2)) { int i; int arraysize =
json_array_size(obj2); printf("Location arraysize:
%d\n", arraysize);
for(i=0; i<arraysize; i++){ json_t* obj3 =
json_array_get(obj2, i); if(json_is_object(obj3)){ json_t* obj4; obj4 =
json_object_get(obj3, "state1"); if(json_is_integer(obj4)){ iValue =
json_integer_value(obj4); printf("[%d]
state1: %d\n", i, iValue); } obj4 =
json_object_get(obj3, "state2"); if(json_is_integer(obj4)){ iValue =
json_integer_value(obj4); printf("[%d]
state2: %d\n", i, iValue); } obj4 =
json_object_get(obj3, "state3");
if(json_is_integer(obj4)){ iValue =
json_integer_value(obj4); printf("[%d]
state3: %d\n", i, iValue); } } } }
}
printf("------------------------------------\n"); }
int main(){
char block[65535];
char *file = "json.txt";
int fd = open(file, O_RDONLY);
if (fd < 0) { // open 失敗 fprintf(stderr, "open(%s)
errror:%d\n", file, fd); return -1;
}
int size = read(fd, block, sizeof(block));
if (size < 0) { fprintf(stderr, "read()
errror:%d\n", fd); close(fd); return -1;
}
close(fd);
parseJson((const char*)block, size); } |
makefile
EXEC = jsontest OBJS = main.o \
all : clean $(EXEC)
clean : -rm
-f $(EXEC) *.elf *.gdb *.o *~
$(EXEC): $(OBJS) gcc -g -O0 -o $@ $(OBJS) -lm -ljansson
%.o: %.c gcc
-c -g3 -O0 -o $@ $<
|
実行結果
$ ./jsontest ------------------------------------ dateTime: 2020-10-24 19:13:49 eventType: DependOnSequentialEvent valPercent(double): 83.700000 alive: yes isScript: true Location arraysize: 3 [0] state1: 98 [0] state2: 44493 [0] state3: 298 [1] state1: 198 [1] state2: 144493 [1] state3: 1298 [2] state1: 298 [2] state2: 244493 [2] state3: 2298 ------------------------------------ |