이것을 파싱하고 객체를 관리 하는 라이브러리중 하나로 JsonCPP 를 사용하여 안에 데이터를 순회 하는 샘플을 만들어 볼겁니다.
들어가기 전에 개발된 샘플은 Visual Studio 2017 버젼에서 제작 된겁니다.
JsonCPP는 별도 라이브러리를 생성할수 있게 소스를 제공합니다.
제가 사용한 라이브러리는 예전에 구한건데 어디서 구한 소스 인지는 기억이 나질 않네요
Visual Studio 2017 에서 쓰기 위해서 2017 맞춰서 별도로 빌드 했습니다. 빌드한 라이브러리는 올려 둘테니 사용하시면 됩니다.
샘플 구성은 TestJson.json 파일을 읽어서 파싱하고 안에 내용을 순회 하며 결과를 출력하는 샘플입니다.
CString sFilePath; sFilePath = "D:\\TestJson.json"; CFile file; if (file.Open(sFilePath, CFile::modeRead)) { LPBYTE lpTmp = new BYTE[file.GetLength()]; memset(lpTmp, 0x00, file.GetLength()); unsigned long nReadSize = file.Read(lpTmp, file.GetLength()); if (nReadSize > 0) { CString sReadCon((LPSTR)lpTmp, file.GetLength()); OutputDebugString(_T("Start JsonCPP Parse\n")); Json::Value jJsonData; Json::Reader reader; std::string sReadBuff = sReadCon; if (reader.parse(sReadBuff, jJsonData)) { OutputDebugString(_T("Read Success\n")); doTraversJsonCPP(jJsonData, _T("")); } else { OutputDebugString(_T("Read Failed\n")); } OutputDebugString(_T("End JsonCPP Parse\n")); } }
void doTraversJsonCPP(Json::Value oRoot, CString sKey) { CString sDebugStr; switch (oRoot.type()) { case Json::nullValue: { sDebugStr.Format(_T("[%s]=null\n"), (LPCTSTR)sKey); OutputDebugString(sDebugStr); }break; case Json::intValue: case Json::uintValue: { sDebugStr.Format(_T("[%s]=%d\n"), (LPCTSTR)sKey, oRoot.asUInt()); OutputDebugString(sDebugStr); }break; case Json::realValue: { sDebugStr.Format(_T("[%s]=%f\n"), (LPCTSTR)sKey, oRoot.asDouble()); OutputDebugString(sDebugStr); }break; case Json::booleanValue: { sDebugStr.Format(_T("[%s]=%s\n"), (LPCTSTR)sKey, oRoot.asBool() ? _T("true") : _T("false")); OutputDebugString(sDebugStr); }break; case Json::stringValue: { CString sValue; sValue = oRoot.asCString(); sDebugStr.Format(_T("[%s]=%s\n"), (LPCTSTR)sKey, (LPCTSTR)sValue); OutputDebugString(sDebugStr); }break; case Json::objectValue: { sDebugStr.Format(_T("[%s]=Object\n"), (LPCTSTR)sKey); OutputDebugString(sDebugStr); Json::Value::Members members(oRoot.getMemberNames()); CString sPath; for (auto name : members) { CString sName; sName = name.c_str(); if (sKey != _T("")) { sPath.Format(_T("%s.%s"), (LPCTSTR)sKey, (LPCTSTR)sName); } else { sPath = sName; } doTraversJsonCPP(oRoot[name], sPath); } }break; case Json::arrayValue: { sDebugStr.Format(_T("[%s]=Array\n"), (LPCTSTR)sKey); OutputDebugString(sDebugStr); unsigned int nArrCnt = oRoot.size(); CString sPath; for (unsigned int index = 0; index < nArrCnt; ++index) { sDebugStr.Format(_T("[%s][%d]\n"), (LPCTSTR)sKey, index); OutputDebugString(sDebugStr); if (sKey != _T("")) { sPath.Format(_T("%s[%d]"), (LPCTSTR)sKey, index); } else { sPath.Format(_T("[%d]"), index); } doTraversJsonCPP(oRoot[index], sPath); } }break; } }
보면 아시겠지만 doTraversJsonCPP 함수는 재귀 함수 입니다.
사용을 하시기 위해서는 두가지를 선행 하셔야 합니다.
Json.h 파일을 인클루드 하셔야 하고요.
json_vc2017_libmtd.lib 파일을 링크 옵션에 추가 하시면 됩니다.
만약에 파싱하시는 Json 파일이 UTF8 인코딩이 되어 있으면 한글이 깨져서 나올겁니다.
소스에 .asCString() 해서 값을 얻어 오는 부분이 있는데 이값을 UniCode에서 MutiByteCode 로 변환을 하셔야 합니다.
변환 하는 방법은 제 블로그에 내용이 있으니 참조 하시면 됩니다.
https://blog.naver.com/berdo_seok/220931299353
제가 빌드한 환경은 MutiByte 환경입니다.
VisualStudio 2017로 기본 프로젝트 생성하시게 되면 UniCode 로 생성이 되실겁니다.
제가 빌드한 JsonCPP 라이브러리는 MultiByte 환경으로 빌드가 되어 있으니
UinCode에서 사용하시는 분이라면 CString 변수에 .asCString() 로 값을 넣으실때에는
MutilByte To UniCode 를 사용 하셔야 합니다.
https://blog.naver.com/berdo_seok/220931302777
설명은 드렸는데 잘 모르시겠으면 댓글을 남겨 주시면 답변 드리겠습니다. ^^
내용은 여기 까지고 라이브러리와 헤더 파일은 별도로 올려 둘테니 쓰실분은 받으시면 됩니다.
Json.zip : 헤더파일, json_vc2017_libmtd.lib (멀티바이트 디버그용), json_vc2017_libmt.lib(멀티바이트 릴리즈용)
파일은 네이버 블로그에 있으니 여기서 받아가시기 바랍니다. ^^
https://blog.naver.com/berdo_seok/221789982110
댓글 없음:
댓글 쓰기