소프트웨어 개발 과정에서 설정 파일 관리는 필수적인 작업입니다. 설정 파일은 프로젝트 유연성 향상과 반복 작업 감소에 기여하며, 디버깅에도 유용합니다. 일반적인 텍스트 형식부터 JSON, XML, Protocol Buffer 등 구조화된 형식까지 다양한 파일 형식이 존재합니다. 이번 글에서는 C++ 환경에서 yaml-cpp 라이브러리를 활용한 YAML 설정 파일 처리 방법을 설명합니다.
yaml-cpp 라이브러리
yaml-cpp는 GitHub에서 공개된 C++ 라이브러리로, 링크에서 소스코드를 확인할 수 있습니다. 이 라이브러리는 CMake를 기반으로 빌드됩니다.
소스코드 다운로드 후 build 폴더 생성:
mkdir build
build 폴더로 이동 후 CMake 실행:
cd build
cmake ..
CMake 명령어 뒤에 ..가 위치하는 이유는 상위 디렉토리의 CMakeLists.txt 파일을 참조하기 위함입니다.
기본적으로 정적 라이브러리(.a 파일)가 생성되며, 동적 라이브러리 생성 시 -D BUILD_SHARED_LIBS=ON 옵션 추가:
cmake .. -D BUILD_SHARED_LIBS=ON
빌드 완료 후 생성된 라이브러리 및 헤더 파일을 프로젝트에 포함하면 사용 가능합니다.
YAML 파일 읽기
예제 설정 파일: settings.yaml
name: frank
gender: male
age: 25
abilities:
c++: 1
java: 1
android: 1
python: 1
읽기 예제 코드: main.cpp
#include <iostream>
#include "include/yaml-cpp/yaml.h"
#include <fstream>
using namespace std;
int main() {
YAML::Node config = YAML::LoadFile("../settings.yaml");
cout << "name: " << config["name"].as<string>() << endl;
cout << "gender: " << config["gender"].as<string>() << endl;
cout << "age: " << config["age"].as<int>() << endl;
for(YAML::const_iterator it = config["abilities"].begin(); it != config["abilities"].end(); ++it) {
cout << it->first.as<string>() << ": " << it->second.as<int>() << endl;
}
return 0;
}
CMakeLists.txt 예시:
cmake_minimum_required(VERSION 3.2)
project(yaml_example)
add_definitions(-std=c++11)
include_directories(include)
set(SOURCES main.cpp)
add_executable(config_reader ${SOURCES})
target_link_libraries(config_reader ${CMAKE_HOME_DIRECTORY}/lib/libyaml-cpp.so)
노드 개념
YAML::Node는 파싱된 데이터를 저장하는 핵심 구조체입니다.
LoadFile() 메서드를 통해 파일을 로드할 수 있으며,
as<T>() 함수를 사용해 데이터 타입을 변환할 수 있습니다.
시퀀스 탐색
abilities 항목의 요소를 순회하는 방법:
for(YAML::const_iterator it = config["abilities"].begin(); it != config["abilities"].end(); ++it) {
cout << it->first.as<string>() << ": " << it->second.as<int>() << endl;
}
데이터 타입 확인
YAML의 기본 타입은 Scalar, Sequence, Map으로 구분됩니다. 타입 확인 예제:
YAML::Node test1 = YAML::Load("[1,2,3]");
cout << "Type: " << test1.Type() << endl; // 시퀀스 타입
YAML::Node test2 = YAML::Load("value");
cout << "Type: " << test2.Type() << endl; // 스칼라 타입
YAML::Node test3 = YAML::Load("{key: value}");
cout << "Type: " << test3.Type() << endl; // 맵 타입
설정 파일 쓰기
파일에 데이터를 추가하고 저장하는 방법:
ofstream output("output.yaml");
config["score"] = 95;
output << config;
output.close();
이 예제는 output.yaml 파일에 새로운 항목을 추가합니다.