뭉근 : 느긋하게 타는 불

wofstream을 사용하여 로그를 기록하는데 이상하게 한글만 출력이 안되었다. 입력 버퍼에도 잘 기록되었는데 안되다니 뭔가 이상했다. 출력된 로그 파일을 보니 영문과 숫자까지만 출력이 되고 그 뒤로 출력되어야할 한글 문자열부터 출력이 되지 않았다. 궁금해서 헥스 편집기로 열어서 보니 아래와 같이 아스키코드로 저장되어 있는 것을 확인할 수 있었다.

   

   

이 무슨 어이없는 일이란 말인가? wofstream으로 출력했으니 당연히 wide 문자로 나와야한다고 생각했는데 큰 오산이었다. 뭐 결국에 해결하고 생각해보면 당연한게 wofstream은 wchar_t 형태의 문자열을 파일로 출력하는 클래스기 때문에 파일 최적화를 위해서 굳이 wchar_t 형태로 내보낼 필요가 없다는 것이다.

wofstream에서 한글 출력을 설정하기 위해서는 코드에 간단하게

   

std::locale::global(std::locale("Korean"));

   

를 추가하면 된다. 하지만 코드의 어디다 넣어야 될까? 파일 쓰기 함수 전에? 파일 오픈 전에? 답은 wofstream의 인스턴스가 생성되기 전이다. (이거 떄문에 시간을 얼마나 소비했는지…) 아래는 이를 증명하는 코드이다.

   

   

코드에 적혀있는데로 wofstream은 인스턴스가 생성될 때 locale이 설정된다. 이 설정된 locale은 이후에 locale이 변경되어도 생성된 wofstream에 그대로 유지된다. 아마도 스트림별 다양한 locale을 지원하기 위해 이렇게 했나 싶다. 뭐.. 이것도 생각해보면 당연하지만…

코드는 locale 설정 전에 메모리에 할당된 스트림과 설정 후에 메모리에 할당된 스트림을 사용하여 파일에 한글 출력을 테스트한다. 위 코드를 컴파일 후 실행해보면 아래와 같이 locale 설정 전에 할당된 wofstream은 0kb로 한글을 출력하지 못한다.

   

   

이렇게 해결 방법을 알아도 문제가 되는 경우가 있는데 전역 변수(정적 변수)의 경우 locale 설정보다 먼저 메모리에 할당될 수 있다. 어쨌든 문제는 해결했으니 … bye!

   

이번 포스트 요약

wofstream은 기본 설정 사용시 wchar_t 형태의 파일 출력을 보장하지 않는다.

wofstream 인스턴스 생성 전, 즉 메모리에 할당되기 전에 locale 설정을 해야한다.

   

코드

int _tmain(int argc, _TCHAR* argv[])

{

/*

wofstream은 메모리에 할당될 때 locale이 설정된다.

이 설정된 locale은 이후에 locale이 변경되어도 유지된다.

*/

std::wofstream fstream_locale_before;

std::locale::global(std::locale("Korean"));

std::wofstream fstream_locale_after;

   

fstream_locale_before.open( _T("..\\test before locale setting.txt") );

fstream_locale_before << _T("한글 파일 출력 테스트") << std::endl;

fstream_locale_before.close();

   

fstream_locale_after.open( _T("..\\test after locale setting.txt") );

fstream_locale_after << _T("한글 파일 출력 테스트") << std::endl;

fstream_locale_after.close();

   

return 0;

}

   

'프로그래밍' 카테고리의 다른 글

Rstudio 3.3.0 스케일링 문제  (0) 2016.05.06
드라이버 개발 삽질 #1  (0) 2015.03.12
ifstream 64  (0) 2014.09.25
CPP 벡터 반복문 중 원소 지우기  (0) 2014.09.22
가상 함수 테스트  (0) 2014.07.05