programing

C++에서 json 파일을 읽는 중

goodsources 2023. 2. 10. 21:49
반응형

C++에서 json 파일을 읽는 중

JSON 파일을 읽으려고 합니다.지금까지의 사용법은,jsoncpp도서관.하지만 그 서류는 제가 이해하기 어렵습니다.누가 그것이 무엇을 하는지 평이하게 설명해 줄 수 있나요?

예를 들어,people.json다음과 같이 표시됩니다.

{"Anna" : { 
      "age": 18,
      "profession": "student"},
 "Ben" : {
      "age" : "nineteen",
      "profession": "mechanic"}
 }

이걸 읽으면 어떻게 되죠?어떤 종류의 데이터 구조를 만들 수 있습니까?people내가 색인화 할 수 있는 것은Anna그리고.Ben게다가age그리고.profession의 데이터 타입은 무엇입니까?people(내포된) 지도와 비슷하다고 생각했는데 지도 값은 항상 같은 타입이어야 하지 않나요?

나는 이전에 python을 사용한 적이 있는데, 나의 "목표" (C++에 대해 잘못 설정될 수 있음)는 네스트된 python 사전과 동등한 것을 얻는 것이다.

  1. 예, 중첩된 데이터 구조를 생성할 수 있습니다.people에 의해 색인화할 수 있습니다.Anna그리고.Ben단, 직접 인덱스를 작성할 수 없습니다.age그리고.profession(코드의 이 부분에 대해 설명하겠습니다).

  2. 데이터 유형:people종류Json::Value(jsoncpp로 정의됩니다).네, 네스트된 지도와 비슷하지만Value는 여러 유형을 저장 및 액세스할 수 있도록 정의된 데이터 구조입니다.이 맵은 맵과 비슷합니다.string열쇠로서 그리고Json::Value그 가치로.이 지도는 또 다른 지도일 수도 있습니다.unsigned int열쇠로서Json::Value값으로 지정합니다(json 배열의 경우).

코드는 다음과 같습니다.

//if include <json/value.h> line fails (latest kernels), try also:
//  #include <jsoncpp/json/json.h>
#include <json/value.h>
#include <fstream>

std::ifstream people_file("people.json", std::ifstream::binary);
Json::Value people;
people_file >> people;

cout<<people; //This will print the entire json object.

//The following lines will let you access the indexed objects.
cout<<people["Anna"]; //Prints the value for "Anna"
cout<<people["ben"]; //Prints the value for "Ben"
cout<<people["Anna"]["profession"]; //Prints the value corresponding to "profession" in the json for "Anna"

cout<<people["profession"]; //NULL! There is no element with key "profession". Hence a new empty element will be created.

보시는 바와 같이 json 개체를 인덱싱할 수 있는 것은 입력 데이터의 계층뿐입니다.

GitHub에 있는 nlohmann의 JSON Repository를 보세요.그것이 JSON과 함께 일하는 가장 편리한 방법이라는 것을 알게 되었습니다.

STL 컨테이너와 동일하게 동작하도록 설계되어 직관적으로 사용할 수 있습니다.

기본적으로 javascript와 C++는 두 가지 다른 원리로 작동합니다.Javascript는 필드 이름인 문자열 키를 값에 일치시키는 "associative array"C++는 메모리에 구조를 배치하기 때문에 처음 4바이트는 에이지인 정수입니다.그러면 "프로페셔널"을 나타내는 고정 wth 32바이트 스트링이 있을 수 있습니다.

javascript는 "나이"가 한 레코드에서는 18세, 다른 레코드에서는 "나이"와 같은 것들을 처리합니다.C++는 할 수 없습니다.(단, C++가 훨씬 빠릅니다.)

따라서 JSON을 C++로 처리하려면 관련 어레이를 처음부터 구축해야 합니다.그런 다음 값에 유형 태그를 붙여야 합니다.정수, 실제 값(아마 "double"로 반환), 부울, 문자열입니까?따라서 JSON C++ 클래스는 상당히 큰 코드 청크입니다.실제로 우리가 하고 있는 것은 Javascript 엔진의 일부를 C++에 구현하는 것입니다.다음으로 JSON 파서를 문자열로 전달하고 이를 토큰화하여 C++에서 JSON을 쿼리하는 함수를 제공합니다.

Fedora 33에 대한 최소 작업 예제 완성

sudo dnf install jsoncpp-devel.

프로젝트 폴더에 다음 파일을 저장하십시오.

people.json

{
    "Anna":
    { 
        "age": 18,
            "profession": "student"
        },
    "Ben":
    {
        "age" : "nineteen",
        "profession": "mechanic"
    }
}

main.cpp

#include <iostream>
#include <fstream>
#include <json/json.h>

int main()
{
    Json::Value people;
    std::ifstream people_file("people.json", std::ifstream::binary);
    people_file >> people;

    std::cout << people["Anna"] << "\n";
    std::cout << people["Anna"]["profession"] << "\n";
}

「」로 합니다.g++ -ljsoncpp main.cpp. 에 전화하고 있습니다부르기./a.out 낳다

산출량

{
    "age" : 18,
    "profession" : "student"
}
"student"

c++ boost::property_tree::ptree 를 사용하여 json 데이터를 해석할 수 있습니다.다음은 json 데이터의 예입니다.각 하위 노드 내에서 이름을 바꾸면 더 쉬워집니다.

#include <iostream>                                                             
#include <string>                                                               
#include <tuple>                                                                

#include <boost/property_tree/ptree.hpp>                                        
#include <boost/property_tree/json_parser.hpp> 
 int main () {

    namespace pt = boost::property_tree;                                        
    pt::ptree loadPtreeRoot;                                                    

    pt::read_json("example.json", loadPtreeRoot);                               
    std::vector<std::tuple<std::string, std::string, std::string>> people;      

    pt::ptree temp ;                                                            
    pt::ptree tage ;                                                            
    pt::ptree tprofession ;                                                     

    std::string age ;                                                           
    std::string profession ;                                                    
    //Get first child                                                           
    temp = loadPtreeRoot.get_child("Anna");                                     
    tage = temp.get_child("age");                                               
    tprofession = temp.get_child("profession");                                 

    age =  tage.get_value<std::string>();                                       
    profession =  tprofession.get_value<std::string>();                         
    std::cout << "age: " << age << "\n" << "profession :" << profession << "\n" ;
    //push tuple to vector                                                      
    people.push_back(std::make_tuple("Anna", age, profession));                 

    //Get Second child                                                          
    temp = loadPtreeRoot.get_child("Ben");                                      
    tage = temp.get_child("age");                                               
    tprofession = temp.get_child("profession");                                 

    age =  tage.get_value<std::string>();                                       
    profession  =  tprofession.get_value<std::string>();                        
    std::cout << "age: " << age << "\n" << "profession :" << profession << "\n" ;
    //push tuple to vector                                                      
    people.push_back(std::make_tuple("Ben", age, profession));                  

    for (const auto& tmppeople: people) {                                       
        std::cout << "Child[" << std::get<0>(tmppeople) << "] = " << "  age : " 
        << std::get<1>(tmppeople) << "\n    profession : " << std::get<2>(tmppeople) << "\n";
    }  
}

json 구성 파일을 읽는 예(완전한 소스 코드 포함):

https://github.com/sksodhi/CodeNuggets/tree/master/json/config_read

 > pwd
/root/CodeNuggets/json/config_read
 > ls
Makefile  README.md  ReadJsonCfg.cpp  cfg.json
 > cat cfg.json 
{
   "Note" : "This is a cofiguration file",
   "Config" : { 
       "server-ip"     : "10.10.10.20",
       "server-port"   : "5555",
       "buffer-length" : 5000
   }   
}
 > cat ReadJsonCfg.cpp 
#include <iostream>
#include <json/value.h>
#include <jsoncpp/json/json.h>
#include <fstream>

void 
displayCfg(const Json::Value &cfg_root);

int
main()
{
    Json::Reader reader;
    Json::Value cfg_root;
    std::ifstream cfgfile("cfg.json");
    cfgfile >> cfg_root;

    std::cout << "______ cfg_root : start ______" << std::endl;
    std::cout << cfg_root << std::endl;
    std::cout << "______ cfg_root : end ________" << std::endl;

    displayCfg(cfg_root);
}       

void 
displayCfg(const Json::Value &cfg_root)
{
    std::string serverIP = cfg_root["Config"]["server-ip"].asString();
    std::string serverPort = cfg_root["Config"]["server-port"].asString();
    unsigned int bufferLen = cfg_root["Config"]["buffer-length"].asUInt();

    std::cout << "______ Configuration ______" << std::endl;
    std::cout << "server-ip     :" << serverIP << std::endl;
    std::cout << "server-port   :" << serverPort << std::endl;
    std::cout << "buffer-length :" << bufferLen<< std::endl;
}
 > cat Makefile 
CXX = g++
PROG = readjsoncfg

CXXFLAGS += -g -O0 -std=c++11

CPPFLAGS += \
        -I. \
        -I/usr/include/jsoncpp

LDLIBS = \
                 -ljsoncpp

LDFLAGS += -L/usr/local/lib $(LDLIBS)

all: $(PROG)
        @echo $(PROG) compilation success!

SRCS = \
        ReadJsonCfg.cpp
OBJS=$(subst .cc,.o, $(subst .cpp,.o, $(SRCS)))

$(PROG): $(OBJS)
        $(CXX) $^ $(LDFLAGS) -o $@

clean:
        rm -f $(OBJS) $(PROG) ./.depend

depend: .depend

.depend: $(SRCS)
        rm -f ./.depend
        $(CXX) $(CXXFLAGS) $(CPPFLAGS) -MM $^ >  ./.depend;

include .depend
 > make
Makefile:43: .depend: No such file or directory
rm -f ./.depend
g++ -g -O0 -std=c++11 -I. -I/usr/include/jsoncpp -MM ReadJsonCfg.cpp >  ./.depend;
g++ -g -O0 -std=c++11 -I. -I/usr/include/jsoncpp  -c -o ReadJsonCfg.o ReadJsonCfg.cpp
g++ ReadJsonCfg.o -L/usr/local/lib -ljsoncpp -o readjsoncfg
readjsoncfg compilation success!
 > ./readjsoncfg 
______ cfg_root : start ______
{
        "Config" : 
        {
                "buffer-length" : 5000,
                "server-ip" : "10.10.10.20",
                "server-port" : "5555"
        },
        "Note" : "This is a cofiguration file"
}
______ cfg_root : end ________
______ Configuration ______
server-ip     :10.10.10.20
server-port   :5555
buffer-length :5000
 > 

다음은 json 파일에서 더 쉽게 읽을 수 있는 다른 방법입니다.

#include "json/json.h"

std::ifstream file_input("input.json");
Json::Reader reader;
Json::Value root;
reader.parse(file_input, root);
cout << root;

그러면 다음과 같은 값을 얻을 수 있습니다.

cout << root["key"]

이런 사람들을 저장하는 것

{"Anna" : { 
  "age": 18,
  "profession": "student"},
"Ben" : {
  "age" : "nineteen",
  "profession": "mechanic"}
 }

특히 서로 다른 사람들이 같은 이름을 가지고 있다면 문제를 일으킬 것이다.

이와 같은 객체를 저장하는 어레이를 사용합니다.

{
  "peoples":[
       { 
           "name":"Anna",  
           "age": 18,
           "profession": "student"
       },
       {
           "name":"Ben",
           "age" : "nineteen",
           "profession": "mechanic"
       } 
  ]
}

이와 같이 개체를 열거하거나 숫자 인덱스로 개체를 액세스할 수 있습니다. json은 스토리지 구조이며 동적으로 정렬하거나 인덱서가 아닙니다.json에 저장된 데이터를 사용하여 필요에 따라 인덱스를 작성하고 데이터에 액세스합니다.

언급URL : https://stackoverflow.com/questions/32205981/reading-json-files-in-c

반응형