개요.
- Json 형식의 문자열에서 특정 키의 값을 추출하는 기능.
- 이런 간단한 기능은 Json 전용 라이브러리 이용할것도 없이 직접 구현해서 활용해도 됨.
- 아래 코드는 Json 문자열 내에 1개의 리스트만 있는 경우에 적용가능하다.
#include "stdafx.h" //for Visual C++ project. | |
#include <iostream> // for std::string | |
/* | |
Json 형식예. | |
{ | |
"ret_code": 0, | |
"ret_msg": "OK", | |
"result": { | |
"order_id": "335fd977-e5a5-4781-b6d0-c772d5bfb95b", | |
"price": 8800, | |
"qty": 1, | |
"updated_at": "2019-11-30T11:03:43.455Z" | |
}, | |
"time_now": "1575111823.458705" | |
} | |
*/ | |
/* | |
Json 형식문자열에서 str_key 에 해당하는 문자열 반환. 단순처리. | |
제한 사항 : 전체 json 문자열 중에서 key 가 1개만 있는 경우. | |
인자. | |
cst_json : Json 문자열. | |
cst_key : 찾고자하는 키 문자열. 예. _T("order_id") | |
*/ | |
CString extract_cst_from_jsoncst(CString cst_json, CString cst_key) | |
{ | |
CString cst_ret; | |
int i_temp; | |
cst_key = _T("\"") + cst_key + _T("\":"); // cst_key 상태 : "order_id": | |
i_temp = cst_json.Find(cst_key); // cst_key 문자열이 있는 인덱스 반환. | |
if (i_temp == -1) // not found key | |
{ | |
// AfxMessageBox(_T("Not found key string")); | |
return _T(""); | |
} | |
cst_ret = cst_json.Mid(i_temp + cst_key.GetLength()); // cst_key 제외 오른쪽 문자열 모두 받음. | |
/// 현재 선택된 문자열이 마지막 지점이면 콤마없고, 중간지점이면 콤마있다. 콤마 여부에 따른 처리 분지. | |
if (cst_ret.Find(_T(",")) == -1) // 콤마없다. Json 의 마지막 지점. | |
{ | |
} | |
else // 콤마 있다. Json 의 중간지점. | |
{ | |
i_temp = cst_ret.FindOneOf(_T(",")); // 처음로 반견되는 , 문자 위치. | |
cst_ret = cst_ret.Left(i_temp); // , 앞에 있는 모든 문자열 받음. | |
} | |
cst_ret = cst_ret.Trim(); // 스페이스 제거. | |
cst_ret = cst_ret.Trim(_T("\"[]{}")); // " 제거. 문자열의 가장 앞과 가장 뒤에 있는 " ] [ {} 모두제거. | |
return cst_ret; | |
} | |
/* | |
Json 형식문자열에서 str_key 에 해당하는 문자열 반환. 단순처리. | |
제한 사항 : 전체 json 문자열 중에서 key 가 1개만 있는 경우. | |
인자. | |
str_json : Json 문자열. | |
str_key : 찾고자하는 키 문자열. 예. "order_id" | |
*/ | |
CString extract_cst_from_jsonstr(std::string str_json, std::string str_key) | |
{ | |
CString cst_json, cst_key; | |
CString cst_ret; | |
int i_temp; | |
//입력받은 string 을 CString 으로. | |
cst_json = CString::CStringT(CA2CT(str_json.c_str())); | |
cst_key = CString::CStringT(CA2CT(str_key.c_str())); // 예. cst_key 상태 : order_id | |
return extract_cst_from_jsoncst(cst_json, cst_key); | |
} | |
/* | |
Json 문자열에서 "cst_key":[{1},{2},...,{n}] {}의 총 수량 n반환. | |
- 주의사항 : {} 내부에 또 {} 형식 있을 수 있음. "cst_key":[{1{}},{2{}},...,{n{}}] . 따라서 중요한 구분자는 },{ 임. | |
반환값. | |
-1 : cst_key_list 에 해당하는 키 없음. | |
-2 : "cst_key_list":{ 형식임. | |
-3 : "cst_key_list":[ 형식아님. | |
-4 : "cst_key_list":[ 형식 있기 한데, [] 도 아니면서 [{ 형식 없음. 정상적인 Json 구문 아님. | |
0 이상 : 정상수행함. 리스트 형식의 요소 수량. "cst_key_list":[ 형식이면서 요소수량 반환. | |
*/ | |
int get_num_list_from_jsoncst(CString cst_json, CString cst_key_list) | |
{ | |
int retv; | |
int i_temp; | |
CString cst_temp_check; | |
CString cst_extract; | |
cst_json.Remove(_T(' '));// 문자열의 공백들 모두제거. | |
if (cst_json.Find(cst_key_list) == -1) return -1;// 키에 해당하는 문자 없다. 예 result | |
cst_temp_check = _T("\"") + cst_key_list + _T("\":null"); // cst_key 상태 예 : "result":null . 의미 : 요소에 항목0개 즉 정보없다는 의미. | |
if (cst_json.Find(cst_temp_check) != -1) return 0; //"result":null 발견됨. 리스트형식이면서 요소 데이터 없음. 즉 0개. | |
cst_temp_check = _T("\"") + cst_key_list + _T("\":{"); // cst_key 상태 예 : "result":{ | |
if (cst_json.Find(cst_temp_check) != -1) return -2; // "result":{ 형식 발견됨. 본 함수는 "result":[ 형식이 있는 것만 처리 가능하므로 에러 리턴. | |
cst_temp_check = _T("\"") + cst_key_list + _T("\":["); // cst_key 상태 예 : "result":[ | |
if( cst_json.Find(cst_temp_check) == -1 ) return -3 ; //"result":[ 발견안됨. 리스트형식 아님 반환. | |
cst_temp_check = _T("\"") + cst_key_list + _T("\":[]"); // cst_key 상태 예 : "result":[] . 의미 : 요소에 항목0개 즉 정보없다는 의미. | |
if(cst_json.Find(cst_temp_check) != -1) return 0 ; //"result":[] 발견됨. 리스트형식이면서 요소 데이터 없음. 즉 0개. | |
cst_temp_check = _T("\"") + cst_key_list + _T("\":[{"); // cst_key 상태 예 : "result":[{ 최소 1개이상의 요소는 있음. | |
i_temp = cst_json.Find(cst_temp_check); | |
if(i_temp == -1) return -4; // "result":[{ 없음. Json 문자열이 규격에 안맞는 오류임. 앞의 0개도 아니면서 "result":[{ 도 없다면 이상한 구문. | |
/// 이 자리 이후는 "result":[{ 뱔견되었고, 최소 1개 이상의 {} 있음. | |
cst_extract = cst_json.Mid(i_temp); // "result":[{ 포함 뒷부분에 있는 모든 문자열 받음. | |
i_temp = cst_extract.Find(_T("}]")); // }] 찾기. | |
cst_extract = cst_extract.Left(i_temp); // }] 앞에 있는 모든 문자열 받음. | |
/// 이제 cst_extract 에서 },{ 수량 찾으면, 이 수량의+1 이 리스트 수량임. | |
retv = cst_extract.Replace(_T("},{"), _T("},{")); // 반환값이 },{ 수량임. [] 속에 {} 1개만 있다면 0. | |
return (retv+1); | |
} | |
/* | |
문자열에서 지정한 인덱스의 {....} 문자열 전체 반환. { } 는 포함하지 않음. | |
- 본 함수 호출전 함수 get_num_list_from_jsoncst 호출하여 {} 수량 확인하여, 2개 이상인 경우에만 호출할것. | |
*/ | |
CString extract_listone_fromjsoncst(CString cst_json, CString cst_key_list, int idx_list) | |
{ | |
int i_temp; | |
CString cst_temp_check; | |
CString cst_extract; | |
cst_json.Remove(_T(' '));// 문자열의 공백들 모두제거. | |
if (cst_json.Find(cst_key_list) == -1) return _T("");// 키에 해당하는 문자 없다. 예 result | |
cst_temp_check = _T("\"") + cst_key_list + _T("\":{"); // cst_key 상태 예 : "result":{ | |
if (cst_json.Find(cst_temp_check) > 0) return _T(""); // 1개 만 있음. | |
cst_temp_check = _T("\"") + cst_key_list + _T("\":[{"); // cst_key 상태 예 : "result":[{ | |
i_temp = cst_json.Find(cst_temp_check); | |
if (i_temp == -1) return _T(""); // "result":[{ 없음. Json 문자열이 규격에 안맞는 오류임. | |
/// 이 자리 이후는 "result":[{ 뱔견되었고, 최소 2개 이상의 {} 있음. | |
cst_extract = cst_json.Mid(i_temp + cst_temp_check.GetLength()); // "result":[{ 는 제외하고 뒷부분 모든 문자열 받음. | |
i_temp = cst_extract.Find(_T("}]")); // }] 찾기. | |
cst_extract = cst_extract.Left(i_temp); // }] 앞에 있는 모든 문자열 받음. 현 상태 예: ...},{},{..},{... | |
// 이제 cst_extract 에서 },{ 수량 찾으면, 이 수량의+1 이 리스트 수량임. | |
int num_list = (1+cst_extract.Replace(_T("},{"), _T("},{"))) ; // 반환값이 },{ 수량임. {}수량은 이 값의 +1 | |
/// idx_list 에 해당하는 {} 문자열만 추출. | |
for (int idx = 0; idx <= idx_list; idx++) | |
{ | |
if (idx == 0) // idx=0 에서는 처리할것 없음. | |
{ | |
} | |
else // idx=1이상은 },{ 의 뒷부분 만 추출. | |
{ | |
i_temp = cst_extract.Find(_T("},{")); // },{ 찾기. | |
cst_extract = cst_extract.Mid(i_temp+3); // },{ 의 뒷부분만 받음. +3 의미 }.{ 제외하고 뒷부분. | |
} | |
} | |
if (idx_list < (num_list - 1)) | |
{ | |
i_temp = cst_extract.Find(_T("},{")); // | |
cst_extract = cst_extract.Left(i_temp); // },{ 의 앞부분만 받음. | |
} | |
else if (idx_list == (num_list - 1)) //마직막 인덱스인 경우엔 현재 받은 cst_extract 그대로 활용하면됨. | |
{ | |
} | |
return cst_extract; | |
} |
여러 개의 리스트 있는 경우 추출코드.
"result" : { }, 처럼 {} 이 1개. 한편, 일반적으로는 "result" : [{...},{...},...,{...}] 처럼 [] 내부에 임의의 수량만큼 {} 들이 있다. 상기 코드의 아래 부분에 있는 2개의 함수이용하여 { ... } 수량 구하고 , 각각의 { ... } 만 추출하고 함수 extract_cst_from_jsonstr 호출하여 필요한 키 값을 추출하면된다.
리스트 키에 요소가 0개인 경우와 1개 이상인 경우 표현형식예.
- 리스트 요소 0개인 경우 "키이름":[] 형식으로 표현되며, 1개이상인 경우에는 "키이름":[{0},{1},...,{}] 형식으로 표현됨.

- 그러나 항상 일관된 규칙이 있는건 아님. 요소 0개인 경우 "키이름":null 로 표현되는 경우도 있음.
- 즉, 해당 데이터 송신하는 측의 데이터 규격에 맞게 핸들링하는 코드 구현해야함.
연관
MFC C++. std::string ,std::wstring, CString , CT2CA, CA2CT,
std::string my_str; std::wstring my_wstr; CString my_cst; // wstring 을 string 으로. my_str.assign(my_wstr.begin(),my_wstr.end()); // string 을 wstring 으로. my_wstr.assign(my_str.begin(),my_str.end..
igotit.tistory.com
C++ REST SDK. Json 형식 다루기 .
개요 C++ REST SDK 기반 Json 형식 만들기, Json 형식 데이터 에서 데이터 요소(키-값) 추출하기. Json 형식 만들기 object 를 바로 json value 형식으로 변환. #include // need for json // Js..
igotit.tistory.com
첫 등록 : 2020.03.22
최종 수정 :
단축 주소 : https://igotit.tistory.com/2510
'VisualStudio.C++.C# > 코딩팁,함수활용,단편' 카테고리의 다른 글
Event Object, CreateEvent.WaitForSingleObject (0) | 2020.04.20 |
---|---|
std::time_t tm gmtime localtime mktime asctime (0) | 2020.03.29 |
MFC C++. std::string ,std::wstring, CString , CT2CA, CA2CT, (0) | 2020.03.22 |
gettimeofday. timeval . 윈도우 에서 구현하기 (0) | 2020.03.20 |
C 에서 파이썬 사용하기 (0) | 2020.03.20 |
댓글