JSON 파일 읽기
개요
JSON(JavaScript Object Notation) 파일은 키와 값의 쌍으로 이루어진 파일이다. 이는 데이터베이스에서 데이터를 저장하고, 데이터를 주고받을 때 자주 사용되는 형식이다. 클라이언트가 사용하는 언어에 관계없이 통일된 데이터를 주고받을 수 있게 해 준다. 일반적인 JSON 파일의 구조는 다음과 같다.
{
"이름": "홍길동",
"나이": 25,
"주소": {
"도시": "서울",
"우편번호": "12345"
},
"취미": ["독서", "여행", "요리"],
"기혼": false
}
위의 예시에서 이름, 나이, 주소, 취미, 기혼은 key고, 홍길동, 25, 도시, 우편번호, 독서, 여행, 요리, false는 각각의 값이다. 이때 값으로 객체와 배열을 포함할 수 있다.
JSON 파일은 데이터 교환, API 응답, 설정 파일 등 다양한 용도로 널리 사용되지만, C++에서 직접 처리하는 것은 어렵다. C++의 std::string은 기본적인 문자열 연산은 지원하지만, 복잡한 문자열 파싱에는 적합하지 않기 때문이다. 또한, C++은 컴파일 시점에 변수의 타입이 결정되는 정적 타입 언어이기 때문에, 동적 타입을 지원하는 JSON을 C++ 타입으로 변환하려면 추가적인 코드와 데이터 구조가 필요해서 까다롭다.
이런 어려움 때문에 C++로 JSON 파서를 구현하는 것은 복잡하며, 여러 오류가 발생할 가능성이 있다. 이를 해결해 주는 라이브러리가 nlohmann의 json.hpp이다. 이 라이브러리를 사용하려면, nlohmann/json의 GitHub 레포지터리에서 json.hpp 파일을 다운로드하여 프로젝트 디렉터리에 추가하면 된다.
본문
다음과 같이 영어 단어 JSON 파일이 있다고 해보자.
먼저 같은 디렉터리 내에 json.hpp 파일과 example.txt 파일을 추가해 준다. 간략하게 설명하자면, 전체 데이터는 중괄호로 둘러싸인 JSON 객체로 시작된다. 그리고 results는 JSON 객체의 유일한 키로서, 대괄호로 둘러싸인 배열이다. 그리고 배열의 각 요소로 단어와 그 뜻으로 이루어져 있다.
그리고 다음과 같이 ifstream을 이용해 파일을 열어준다.
#include <iostream>
#include <string>
#include <fstream>
#include <map>
#include "json.hpp"
using json = nlohmann::json;
int main()
{
std::ifstream file("example.txt", std::ios::in);
if (!file.is_open())
{
std::cerr << "Error opening example.txt.\n";
return 1;
}
C++에서 파일을 읽을 때 입력 파일 스트림 클래스 ifstream을 사용한다. 해당 코드에서는 같은 디렉터리 내에 example.txt라는 파일을 읽은 후, 파일을 읽는 데 실패하면 에러 메시지를 출력하게 설정하였다.
json j;
file >> j;
이제 nlohman::json 타입의 객체 j를 선언하고, 파일 스트림 file에서 JSON 데이터를 읽어 들여, j 객체에 저장하게 하였다. >> 연산자는 json 라이브러리에서 오버로드되어 있어, 스트림에서 JSON 형식의 문자열을 파싱하여 JSON 객체에 저장할 수 있게 된다.
std::map<std::string, std::string> word_map;
for (const auto& result : j["results"])
word_map[result["Vocabulary"].get<std::string>()] = result["meaning"].get<std::string>();
단어 쌍을 저장할 word_map 맵을 선언하고, results키에 연결된 배열의 각 요소를 순회하며 Vocabulary 키의 값과 meaning 키의 값을 문자열로 추출하고 맵에 저장한다.
for (const auto& pair : word_map)
std::cout << pair.first << ": " << pair.second << "\n";
그리고 맵에 있는 값들을 출력해 보면 한글이 깨지는 것을 알 수 있는데, 이는 Window 환경에서 콘솔 창의 기본 인코딩이 UTF-8이 아니기 때문이다. 따라서 프로그램 시작 부분에 콘솔의 인코딩을 UTF-8로 설정해 주면 해결할 수 있다.
...
int main()
{
SetConsoleOutputCP(CP_UTF8);
...
return 0;
}
총합본
#include <iostream>
#include <string>
#include <fstream>
#include <map>
#include "json.hpp"
#include <Windows.h>
using json = nlohmann::json;
int main()
{
SetConsoleOutputCP(CP_UTF8);
std::ifstream file("example.txt", std::ios::in);
if (!file.is_open())
{
std::cerr << "Error opening example.txt.\n";
return 1;
}
json j;
file >> j;
std::map<std::string, std::string> word_map;
for (const auto& result : j["results"])
word_map[result["Vocabulary"].get<std::string>()] = result["meaning"].get<std::string>();
for (const auto& pair : word_map)
std::cout << pair.first << ": " << pair.second << "\n";
return 0;
}
요약
JSON 파일 읽기
1. 정의: 키와 값의 쌍으로 이루어진 텍스트 기반 데이터 파일
2. C++에서 사용
a. nlohamnn의 json.hpp을 이용: JSON 데이터를 파싱 하고, C++ 데이터 구조로 쉽게 변환할 수 있게 해 줌
b. 파일 읽기: C++의 ifstream을 이용하여 효율적이고 안전한 파일 읽기 가능
'Language > C++' 카테고리의 다른 글
[C++] 중복 처리 (1) (0) | 2023.09.07 |
---|---|
[C++] 난수 생성 (0) | 2023.09.04 |
[C++] 문자열 처리 - 연속된 문자열과 동일한 문자열 (2) (0) | 2023.08.26 |
[C++] 문자열 처리 - 연속된 문자열과 동일한 문자열 (1) (0) | 2023.08.25 |
[C++] 싱글톤 패턴의 생성자와 소멸자 동작 이해 - new, delete키워드 with C++ (0) | 2023.08.13 |