인디노트

[LINUX C] C언어에서 JSON (JSON-C) 데이터 읽기 본문

소스 팁/C, C++, C#

[LINUX C] C언어에서 JSON (JSON-C) 데이터 읽기

인디개발자 2018. 10. 22. 16:30

client나 파일을 통해 읽은 JSON type의 데이터를 파싱해 보자.

 

(json설치는 http://blog.naver.com/yababies/220029067066 참조 ) 

 

 

json-c에서 제공하는 다음의 함수를 사용해서 데이터를 읽어보자.

 

json_tokener_parse()

- 읽어들인 JSON type의 데이터를 파싱한다.

json_object_object_get()

- JSON type의 데이터에서 object를 추출한다.

json_object_get_int()

- json object에서 정수값을 추출한다.

json_object_get_string()

- json object에서 string값을 추출한다.

json_object_array_get_idx()

- array type의 json object에서 값을 추출한다.

 

 

다음의 JSON 데이터를 파싱해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
  "header": {
    "dataSize": 1000,
    "dataType": "text",
    "macAddress": "00:00:00:00:00"
  },
  "data": {
    "data1": 1,
    "data2": "TEST2",
    "comment": "This is a test!!",
    "nameInfo": {
      "name": "홍길동",
      "regiid": "1406163000001"
    },
    "phoneNumber": [
      "010-0000-0000",
      "010-1111-1111",
      "010-2222-2222"
    ]
  }
}

 

위의 JSON data는 header영역과 data영역으로 나누어져 있다.

header에는 정수타입의 dataSize와 스트링타입의 dataType, macAddress 3개 필드가 있다.

data에는 정수타입의 data1과 스트링타입의 data2, comment가 있고 json_object타입의 nameInfo와 json_object array타입의 phoneNumber가 있다.

 

 

1. data 파싱 : json_tokener_parse

 

JSON data의 파싱은 기본적으로 json_tokener_parse()를 통해 데이터를 파싱하고

파싱된 데이터를 각각의 json_object에 매칭 시킨 후에 데이터를 추출한다.

아래와 같이 하면 myobj에는 buff의 파싱된 정보가 들어가게 된다.

 

char *buff = "{ \"header\": { \"dataSize\": 1000, \"dataType\": \"text\", \"macAddress\": \"00:00:00:00:00\" }, \"data\": { \"data1\": 1, \"data2\": \"TEST2\", \"comment\": \"This is a test!!\", \"nameInfo\": { \"name\": \"홍길동\", \"regiid\": \"1406163000001\" }, \"phoneNumber\": [ \"010-0000-0000\", \"010-1111-1111\", \"010-2222-2222\" ] } }";

json_object *myobj;

 

myobj = json_tokener_parse(buff); 

 

 

2. data 읽기 : json_object_object_get(), json_object_get_string()

 

실제 데이터를 읽기 위해서는 먼저 object에 원하는 필드를 할당하고 해당 필드를 읽으면 된다.

각 데이터 type별로 json_object_get_int(), json_object_get_double(), json_object_get_boolean()등도 있다.

 

json_object * headerobj, *dval;

 

/* header영역을 headerobj에 링크시킨다. */

headerobj = json_object_object_get(myobj, "header");

 

/* header에서 dataType 필드 위치를 링크시킨다. */

dval = json_object_object_get(headerobj, "dataType");

/* string type은 json_object_get_string()을 통해 데이터를 추출한다. */

printf("dataType : %s\n", json_object_get_string(dval));

 

 

3. array type 읽기: json_object_array_length(), json_object_array_get_idx()

 

위의 phoneNumber와 같은 array type의 테이터는 json_object_array_length()를 통해 데이터의 길이를 가져온 후에

json_object_array_get_idx()를 사용해서 순차적으로 데이터를 읽어 들이면 된다.

 

json_object *dobj, *dval;

int i;

 

 

dobj = json_object_object_get(dataobj, "phoneNumber");

for (i = 0; i < json_object_array_length(dobj); i++)

{

dval = json_object_array_get_idx(dobj, i);

}

 

 

위에서 설명한 것을 보여주는 전체 소스이다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <stdio.h>
#include <json/json.h>
 
int main(int argc, char **argv)
{
/*
{ "header": { "dataSize": 1000, "dataType": "text", "macAddress": "00:00:00:00:00" }, 
   "data": { "data1": 1, "data2": "TEST2", "comment": "This is a test!!", 
        "nameInfo": { "name": "홍길동", "regiid": "1406163000001" }, 
        "phoneNumber": [ "010-0000-0000", "010-1111-1111", "010-2222-2222" ] } }
*/
    char *buff = "{ \"header\": { \"dataSize\": 1000, \"dataType\": \"text\", \"macAddress\": \"00:00:00:00:00\" }, \"data\": { \"data1\": 1, \"data2\": \"TEST2\", \"comment\": \"This is a test!!\", \"nameInfo\": { \"name\": \"홍길동\", \"regiid\": \"1406163000001\" }, \"phoneNumber\": [ \"010-0000-0000\", \"010-1111-1111\", \"010-2222-2222\" ] } }";
    json_object *myobj, *headerobj, *dataobj;
    json_object *dobj, *dval;
    int i;
 
    /* JSON type의 데이터를 읽는다. */
    myobj = json_tokener_parse(buff);
 
    headerobj = json_object_object_get(myobj, "header");
    dataobj   = json_object_object_get(myobj, "data");
 
    /* header 영역 파싱 */
    dval = json_object_object_get(headerobj, "dataType");
    printf("dataType : %s\n", json_object_get_string(dval));
    dval = json_object_object_get(headerobj, "macAddress");
    printf("macAddress : %s\n", json_object_get_string(dval));
 
    /* data 영역 파싱 */
    dval = json_object_object_get(dataobj, "data1");
    printf("data1 : %d\n", json_object_get_int(dval));
    
    /* data.nameInfo 영역 파싱( object안에 object ) */
    dobj = json_object_object_get(dataobj, "nameInfo");
    dval = json_object_object_get(dobj, "name");
    printf("nameInfo.name : %s\n", json_object_get_string(dval));
    dval = json_object_object_get(dobj, "regiid");
    printf("nameInfo.regiid : %s\n", json_object_get_string(dval));
    
    /* data.phoneNumber 파싱 ( array type ) */
    dobj = json_object_object_get(dataobj, "phoneNumber");
    printf("nameInfo.phoneNumber is\n");
    for (i = 0; i < json_object_array_length(dobj); i++)
    {
        dval = json_object_array_get_idx(dobj, i);
        printf("   %s\n", json_object_get_string(dval));
    }
    return(0);
}

 

 

위에 소스 실행 결과이다.

 

 

1
2
3
4
5
6
7
8
9
10
dataType : text
macAddress : 00:00:00:00:00
data1 : 1
nameInfo.name : 홍길동
nameInfo.regiid : 1406163000001
nameInfo.phoneNumber is
   010-0000-0000
   010-1111-1111
   010-2222-2222
 

 

 

 


반응형
Comments