[C++] ini 파일 파라미터 읽기 및 쓰기

오늘은 C++에서 ini 파일을 읽어서, 미리 셋팅된 설정값들을 읽고 쓰는 방법에 대해서 알아본다.

 

ini 파일 구성하기

알고 있는 경로(C:\blog\setting.ini)에다가 아래와 같이 설정해주자.

 

우리가 할 일은 [MODE] 밑에 current_mode name에 있는 값을 읽어오는 것이다.

 

필요한 라이브러리 포함

#include <iostream>  // std::cout 출력
#include <Windows.h> // ini 읽기 & 쓰기
#include <atlstr.h>  // CString 타입 사용

 

소스 코드

아래 코드를 작성하고 나서 buffer를 출력할 때, 그냥 std::cout << buffer << std::endl; 를 하게 되면 출력되지 않는 현상을 볼 수 있다. 왜 그럴까?

int main()
{
	CString path = _T("C:\\blog\\setting.ini");
	TCHAR buffer[MAX_PATH] = { 0, };

	GetPrivateProfileString(_T("MODE"), _T("name"), _T(""), buffer, MAX_PATH, path);
    
	GetPrivateProfileString(_T("MODE"), _T("current_mode"), _T(""), buffer, MAX_PATH, path);

	return 0;
}

필수적으로 확인해야할 것은 현재 프로젝트의 문자 집합이 유니코드인지, 멀티바이트인 지 확인하는 것이다. 두 설정에 따라 코드가 달라진다.

 

※ 문자 집합 확인하는 법

경로: Visual Studio 상단바 - [프로젝트] - [프로젝트 속성] 클릭 후 [구성 속성] - [고급] - [문자 집합]

 

[유니코드] 코드 및 결과

WCharToString( .. )이라는 함수를 만들어서 std::string 타입으로 변환하는 과정이 추가된다.

// 유니코드에서만 필요
std::string WCharToString(const wchar_t* wstr)
{
	int size = WideCharToMultiByte(CP_ACP, 0, wstr, -1, nullptr, 0, nullptr, nullptr);
	std::string str(size, 0);
	WideCharToMultiByte(CP_ACP, 0, wstr, -1, &str[0], size, nullptr, nullptr);
	str.pop_back(); // null 문자 제거
	return str;
}

int main()
{
	CString path = _T("C:\\blog\\setting.ini");
	TCHAR buffer[MAX_PATH] = { 0, };

	GetPrivateProfileString(_T("MODE"), _T("name"), _T(""), buffer, MAX_PATH, path);
	std::cout << WCharToString(buffer) << std::endl;


	GetPrivateProfileString(_T("MODE"), _T("current_mode"), _T(""), buffer, MAX_PATH, path);
	std::cout << WCharToString(buffer) << std::endl;

	return 0;
}

 

출력 결과는 아래와 같다.

 

[멀티바이트] 코드 및 결과

유니코드와는 다르게 그냥 std::string( .. )에 넣으면 된다.

int main()
{
	CString path = _T("C:\\blog\\setting.ini");
	TCHAR buffer[MAX_PATH] = { 0, };

	GetPrivateProfileString(_T("MODE"), _T("name"), _T(""), buffer, MAX_PATH, path);
	std::cout << std::string(buffer) << std::endl;


	GetPrivateProfileString(_T("MODE"), _T("current_mode"), _T(""), buffer, MAX_PATH, path);
	std::cout << std::string(buffer) << std::endl;

	return 0;
}

 

그 결과는 아래와 같다.

 

ini 파일에 쓰기

눈치챈 사람들도 있겠지만, ini 파일 읽기 & 쓰기에는 아래 두 함수가 사용된다.

GetPrivateProfileString( /* ... */ ) ;
WritePrivateProfileString( /* ... */ ) ;

 

[유니코드/멀티바이트 공통] 따라서 아래 코드를 실행하게 되면 current_mode 값이 99로 셋팅되는 것을 볼 수 있다.

WritePrivateProfileString(_T("MODE"), _T("current_mode"), _T("99"), path);

 

함수 반환값

개발자들을 위하여,,, 반환값에 대해 설명한다.

 

📌 GetPrivateProfileString ()

DWORD GetPrivateProfileString(
  LPCTSTR lpAppName,       // 섹션 이름
  LPCTSTR lpKeyName,       // 키 이름
  LPCTSTR lpDefault,       // 기본값
  LPTSTR  lpReturnedString,// 결과 버퍼
  DWORD   nSize,           // 버퍼 크기
  LPCTSTR lpFileName       // INI 파일 경로
);

✅ 반환값

0 - 해당 섹션이나 키가 없고 기본값이 NULL일 때
- 또는 에러 발생 시 (예: 파일 경로 오류, 권한 문제 등)
>0 && < nSize - 읽은 문자열의 길이 (널 문자 제외)
- 즉, 성공적으로 읽었고 길이는 반환값
== nSize - 1 - 문자열이 버퍼 크기보다 길어서 잘린 경우
- 주의: 이 경우 문자열이 완전히 읽히지 않았을 수 있음

 

📌 WritePrivateProfileString ()

BOOL WritePrivateProfileString(
  LPCTSTR lpAppName,  // 섹션 이름
  LPCTSTR lpKeyName,  // 키 이름
  LPCTSTR lpString,   // 저장할 문자열
  LPCTSTR lpFileName  // INI 파일 경로
);

✅ 반환값

TRUE (1) 성공적으로 쓰기 작업 완료
FALSE (0) 실패 (예: 경로 없음, 권한 문제, 디스크 오류 등)

 

실패했을 때는 GetLastError()를 이용해서 구체적인 내용을 확인할 수 있다 !

 

참조