TIL (Today I Learned)/REST API
[jansson] json parsing
loki d
2021. 9. 27. 17:53
728x90
json parsing
- dapi.kakao.com /v2/local/search/keyword.json?query=eluon 결과
{ "documents": [ { "address_name": "경기 성남시 분당구 삼평동 670", "category_group_code": "", "category_group_name": "", "category_name": "서비스,산업 \u003e 인터넷,IT \u003e 소프트웨어", "distance": "", "id": "18634438", "phone": "070-4489-1000", "place_name": "이루온", "place_url": "http://place.map.kakao.com/18634438", "road_address_name": "경기 성남시 분당구 대왕판교로 660", "x": "127.10714197082693", "y": "37.40077576672964" }, { "address_name": "경기 성남시 분당구 삼평동 670", "category_group_code": "", "category_group_name": "", "category_name":"서비스,산업 \u003e 제조업 \u0 03e 전기,전자 \u003e 보안제품", "distance": "", "id": "1676681776", "phone": "070-4489-1078", "place_name": "이루온아이앤에스", "place_url": "http://place.map.kakao.com/1676681776", "road_address_name": "경기 성남시 분당구 대왕판교로 660", "x": "127.106674018018", "y": "37.4005076856004" }, { "address_name": "경기 성남시 분당구 삼평동 670", "category_group_code": "", "category_group_name": "", "category_name": "서비스,산업 \u003e 인터넷,IT \u003e 소프트웨어", "distance": "", "id": "16059856", "phone": "1588-6670", "place_name": "이루온엘비에스", "place_url": "http://place.map.kakao.com/16059856", "road_address_name": "경기 성남시 분당구 대왕판교로 660", "x": "127.10738515856319", "y": "37.40103233706369" } ], "meta": { "is_end": true, "pageable_count": 3, "same_name": { "keyword": "eluon", "region": [], "selected_region": "" }, "total_count": 3 } }
jansson을 이용한 json parsing - 출력
접기/펼치기 버튼
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <jansson.h>
#include <stdbool.h>
void error_handling(char* msg);
char buffer[BUFSIZ];
int main(int argc, char *argv[]){
int status;
struct addrinfo hints;
struct addrinfo *servinfo, *tmp; // 결과를 저장할 변수
char host[256];
int c_socket;
struct sockaddr_in c_addr;
char message_fmt[] = "GET %s HTTP/1.0\r\nHost: %s\r\nAuthorization: KakaoAK %s\r\n\r\n";
int left_len, sent_len, recv_len, bytes;
char rcvBuffer[BUFSIZ];
char data[BUFSIZ];
char* afterData;
json_t *root;
json_error_t error;
int i;
c_socket = socket(PF_INET, SOCK_STREAM, 0);
memset(&hints, 0, sizeof(hints)); // hints 구조체의 모든 값을 0으로 초기화
hints.ai_family = AF_UNSPEC; // IPv4 IPv6 상관없이 결과 모두 반환
hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
if(argc !=4){
fprintf(stderr, "Usage : <host> <resource> <API_KEYS>\nex) ./search_keyword dapi.kakao.com /v2/local/search/keyword.json?query=<query> <API_KEYS>\n");
return -1;
}
status = getaddrinfo(argv[1], "80", &hints, &servinfo);
tmp = servinfo;
getnameinfo(tmp->ai_addr, tmp->ai_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST);
sprintf(buffer, message_fmt, argv[2], argv[1], argv[3]);
memset(&c_addr, 0, sizeof(c_addr));
c_addr.sin_addr.s_addr = inet_addr(host);
c_addr.sin_family = AF_INET;
c_addr.sin_port = htons(80);
if(connect(c_socket, (struct sockaddr *) &c_addr, sizeof(c_addr)) == -1){
error_handling("Can not connect");
close(c_socket);
return -1;
}
left_len = strlen(buffer);
sent_len = 0;
do{
bytes = write(c_socket, buffer + sent_len, left_len - sent_len);
if(bytes <0)
error_handling("write()Error\n");
if(bytes ==0)
break;
sent_len +=bytes;
}while(sent_len < left_len);
left_len = strlen(rcvBuffer);
sent_len = 0;
do{
memset(rcvBuffer, 0, sizeof(rcvBuffer));
bytes = read(c_socket, rcvBuffer, 1024);
fprintf(stdout, "%s ", rcvBuffer);
if(bytes < 0)
error_handling("read() error\n");
if(bytes ==0)
break;
recv_len +=bytes;
//sprintf(data, "%s%s", data, rcvBuffer);
strcat(data, rcvBuffer);
}while(1);
if(recv_len == left_len)
error_handling("Error\n");
afterData = strstr(data, "{");
root = json_loads(afterData, 0, &error);
if(!root)
{
fprintf(stderr, "Error : on line %d : %s \n", error.line, error.text);
return 1;
}
if(root){
json_t *jsonData = json_object_get(root, "documents");
if(json_is_array(jsonData)){
const int length = json_array_size(jsonData);
for(i=0; i<length; i++){
json_t *jsonObject = json_array_get(jsonData, i);
json_t *jsonAddress_name = json_object_get(jsonObject, "address_name");
const char *address_name = json_string_value(jsonAddress_name);
json_t *jsonCategory_group_code = json_object_get(jsonObject, "category_group_code");
const char *category_group_code = json_string_value(jsonCategory_group_code);
json_t *jsonCategory_group_name = json_object_get(jsonObject, "category_group_name");
const char *category_group_name = json_string_value(jsonCategory_group_name);
json_t *jsonCategory_name= json_object_get(jsonObject, "category_name");
const char *category_name= json_string_value(jsonCategory_name);
json_t *jsonDistance= json_object_get(jsonObject, "distance");
const char *distance= json_string_value(jsonDistance);
json_t *jsonId= json_object_get(jsonObject, "id");
const char *id= json_string_value(jsonId);
json_t *jsonPhone= json_object_get(jsonObject, "phone");
const char *phone= json_string_value(jsonPhone);
json_t *jsonPlace_name= json_object_get(jsonObject, "place_name");
const char *place_name= json_string_value(jsonPlace_name);
json_t *jsonPlace_url = json_object_get(jsonObject, "place_url");
const char *place_url= json_string_value(jsonPlace_url);
json_t *jsonRoad_address_name= json_object_get(jsonObject, "road_address_name");
const char *road_address_name = json_string_value(jsonRoad_address_name);
json_t *jsonX= json_object_get(jsonObject, "x");
const char *x= json_string_value(jsonX);
json_t *jsonY= json_object_get(jsonObject, "y");
const char *y= json_string_value(jsonY);
printf("\naddress_name = %s\ncategory_group_code = %s\ncategory_group_name = %s\ncategory_name = %s\ndistance = %s\nid = %s\nphone = %s\nplace_name = %s\nplace_url = %s\nroad_address_name = %s\nx=%s\ny=%s\n\n\n", address_name, category_group_code, category_group_name, category_name,distance,id,phone,place_name,place_url,road_address_name,x,y);
}
}
json_t *jsonMetaData = json_object_get(root, "meta");
json_t *jsonIs_end = json_object_get(jsonMetaData, "is_end");
const short is_end = json_boolean_value(jsonIs_end);
json_t *jsonPageable_count = json_object_get(jsonMetaData, "pageable_count");
const int pageable_count = json_integer_value(jsonPageable_count);
json_t *jsonTotal_count = json_object_get(jsonMetaData, "total_count");
const int total_count = json_integer_value(jsonTotal_count);
printf("Meta\nis_end = %d\npageable_count = %d\ntotal_count = %d\n",is_end, pageable_count, total_count);
json_t *jsonSame_name = json_object_get(jsonMetaData, "same_name");
json_t *jsonKeyword = json_object_get(jsonSame_name, "keyword");
const char *keyword = json_string_value(jsonKeyword);
json_t *jsonSelected_region = json_object_get(jsonSame_name, "selected_region");
const char *selected_region = json_string_value(jsonSelected_region);
// json_t *jsonregions = json_object(jsonsame_name, "region");
// const char *region = "";
// if(json_is_array(jsonRegions)){
// const int regionLength = json_array_size(jsonRegions);
// for(i=0; i<regionLength; i++){
// json_t *jsonObject = json_array_get(jsonRegions, i);
// strcat(region, jsonObject);
// }
// }
// printf("\nsame_name\nkeyword = %s\nregion = %s \nselected_region = %s\n", keyword, region, selected_region);
printf("\nsame_name\nkeyword = %s\n\nselected_region = %s\n", keyword, selected_region);
}
close(c_socket);
freeaddrinfo(servinfo);
}
void error_handling(char* msg){
fputs(msg, stderr);
fputc('\n', stderr);
exit(1);
}
jansson을 이용한 json parsing - 구조체
- 구조체에 각 멤버변수에 GET한 정보를 넣어준다.
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <jansson.h>
#include <stdbool.h>
void error_handling(char* msg);
char buffer[BUFSIZ];
#define DEFAULT_SIZE 512
#define COMM_MAX 5
typedef struct Document_t {
char id [DEFAULT_SIZE] ;
char place_name [DEFAULT_SIZE] ;
char category_group_code [DEFAULT_SIZE] ;
char category_group_name [DEFAULT_SIZE] ;
char category_name [DEFAULT_SIZE] ;
char phone [DEFAULT_SIZE] ;
char address_name [DEFAULT_SIZE] ;
char road_address_name [DEFAULT_SIZE] ;
char x [DEFAULT_SIZE] ;
char y [DEFAULT_SIZE] ;
char place_url [DEFAULT_SIZE] ;
char distance [DEFAULT_SIZE] ;
} Document ;
typedef struct Region_t {
char region [DEFAULT_SIZE] ;
} Region ;
typedef struct SameName_t {
Region regions [COMM_MAX] ;
char keyword [DEFAULT_SIZE] ;
char selected_region [DEFAULT_SIZE] ;
} SameName ;
typedef struct Meta_t {
int total_count ;
int pageable_count ;
short is_end ;
SameName same_name ;
} Meta ;
typedef struct DataSet_t {
Document documents [COMM_MAX] ;
Meta meta ;
} DataSet ;
DataSet dataSet;
int main(int argc, char *argv[]){
int status;
struct addrinfo hints;
struct addrinfo *servinfo, *tmp; // 결과를 저장할 변수
char host[256];
int c_socket;
struct sockaddr_in c_addr;
char message_fmt[] = "GET %s HTTP/1.0\r\nHost: %s\r\nAuthorization: KakaoAK %s\r\n\r\n";
int left_len, sent_len, recv_len, bytes;
char rcvBuffer[BUFSIZ];
char data[BUFSIZ];
char* afterData;
json_t *root;
json_error_t error;
int i;
c_socket = socket(PF_INET, SOCK_STREAM, 0);
memset(&hints, 0, sizeof(hints)); // hints 구조체의 모든 값을 0으로 초기화
hints.ai_family = AF_UNSPEC; // IPv4 IPv6 상관없이 결과 모두 반환
hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
if(argc !=4){
fprintf(stderr, "Usage : <host> <resource> <API_KEYS>\nex) ./search_keyword dapi.kakao.com /v2/local/search/keyword.json?query=<query> <API_KEYS>\n");
return -1;
}
status = getaddrinfo(argv[1], "80", &hints, &servinfo);
tmp = servinfo;
getnameinfo(tmp->ai_addr, tmp->ai_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST);
sprintf(buffer, message_fmt, argv[2], argv[1], argv[3]);
memset(&c_addr, 0, sizeof(c_addr));
c_addr.sin_addr.s_addr = inet_addr(host);
c_addr.sin_family = AF_INET;
c_addr.sin_port = htons(80);
if(connect(c_socket, (struct sockaddr *) &c_addr, sizeof(c_addr)) == -1){
error_handling("Can not connect");
close(c_socket);
return -1;
}
left_len = strlen(buffer);
sent_len = 0;
do{
bytes = write(c_socket, buffer + sent_len, left_len - sent_len);
if(bytes <0)
error_handling("write()Error\n");
if(bytes ==0)
break;
sent_len +=bytes;
}while(sent_len < left_len);
left_len = strlen(rcvBuffer);
sent_len = 0;
do{
memset(rcvBuffer, 0, sizeof(rcvBuffer));
bytes = read(c_socket, rcvBuffer, 1024);
fprintf(stdout, "%s ", rcvBuffer);
if(bytes < 0)
error_handling("read() error\n");
if(bytes ==0)
break;
recv_len +=bytes;
//sprintf(data, "%s%s", data, rcvBuffer);
strcat(data, rcvBuffer);
}while(1);
if(recv_len == left_len)
error_handling("Error\n");
afterData = strstr(data, "{");
root = json_loads(afterData, 0, &error);
if(!root)
{
fprintf(stderr, "Error : on line %d : %s \n", error.line, error.text);
return 1;
}
if(root){
json_t *jsonData = json_object_get(root, "documents");
if(json_is_array(jsonData)){
const int length = json_array_size(jsonData);
if(length > COMM_MAX)
error_handling("Out of index Error\n");
for(i=0; i<length; i++){
json_t *jsonObject = json_array_get(jsonData, i);
json_t *jsonAddress_name = json_object_get(jsonObject, "address_name");
strcpy(dataSet.documents[i].address_name , json_string_value(jsonAddress_name));
json_t *jsonCategory_group_code = json_object_get(jsonObject, "category_group_code");
strcpy(dataSet.documents[i].category_group_code , json_string_value(jsonCategory_group_code));
json_t *jsonCategory_group_name = json_object_get(jsonObject, "category_group_name");
strcpy(dataSet.documents[i].category_group_name , json_string_value(jsonCategory_group_name));
json_t *jsonCategory_name= json_object_get(jsonObject, "category_name");
strcpy(dataSet.documents[i].category_name , json_string_value(jsonCategory_name));
json_t *jsonDistance= json_object_get(jsonObject, "distance");
strcpy(dataSet.documents[i].distance , json_string_value(jsonDistance));
json_t *jsonId= json_object_get(jsonObject, "id");
strcpy(dataSet.documents[i].id , json_string_value(jsonId));
json_t *jsonPhone= json_object_get(jsonObject, "phone");
strcpy(dataSet.documents[i].phone , json_string_value(jsonPhone));
json_t *jsonPlace_name= json_object_get(jsonObject, "place_name");
strcpy(dataSet.documents[i].place_name , json_string_value(jsonPlace_name));
json_t *jsonPlace_url = json_object_get(jsonObject, "place_url");
strcpy(dataSet.documents[i].place_url , json_string_value(jsonPlace_url));
json_t *jsonRoad_address_name= json_object_get(jsonObject, "road_address_name");
strcpy(dataSet.documents[i].road_address_name , json_string_value(jsonRoad_address_name));
json_t *jsonX= json_object_get(jsonObject, "x");
strcpy(dataSet.documents[i].x , json_string_value(jsonX));
json_t *jsonY= json_object_get(jsonObject, "y");
strcpy(dataSet.documents[i].y , json_string_value(jsonY));
printf("\naddress_name = %s\ncategory_group_code = %s\ncategory_group_name = %s\ncategory_name = %s\ndistance = %s\nid = %s\nphone = %s\nplace_name = %s\nplace_url = %s\nroad_address_name = %s\nx=%s\ny=%s\n\n\n", dataSet.documents[i].address_name, dataSet.documents[i].category_group_code, dataSet.documents[i].category_group_name, dataSet.documents[i].category_name, dataSet.documents[i].distance, dataSet.documents[i].id,dataSet.documents[i].phone, dataSet.documents[i].place_name, dataSet.documents[i].place_url,dataSet.documents[i].road_address_name,dataSet.documents[i].x, dataSet.documents[i].y);
}
}
json_t *jsonMetaData = json_object_get(root, "meta");
json_t *jsonIs_end = json_object_get(jsonMetaData, "is_end");
dataSet.meta.is_end = json_boolean_value(jsonIs_end);
json_t *jsonPageable_count = json_object_get(jsonMetaData, "pageable_count");
dataSet.meta.pageable_count = json_integer_value(jsonPageable_count);
json_t *jsonTotal_count = json_object_get(jsonMetaData, "total_count");
dataSet.meta.total_count = json_integer_value(jsonTotal_count);
printf("Meta\nis_end = %d\npageable_count = %d\ntotal_count = %d\n",dataSet.meta.is_end, dataSet.meta.pageable_count, dataSet.meta.total_count);
json_t *jsonSame_name = json_object_get(jsonMetaData, "same_name");
json_t *jsonKeyword = json_object_get(jsonSame_name, "keyword");
strcpy(dataSet.meta.same_name.keyword , json_string_value(jsonKeyword));
json_t *jsonSelected_region = json_object_get(jsonSame_name, "selected_region");
strcpy(dataSet.meta.same_name.selected_region , json_string_value(jsonSelected_region));
printf("\nsame_name\nkeyword = %s\n\nselected_region = %s\n", dataSet.meta.same_name.keyword, dataSet.meta.same_name.selected_region);
}
close(c_socket);
freeaddrinfo(servinfo);
}
void error_handling(char* msg){
fputs(msg, stderr);
fputc('\n', stderr);
exit(1);
}