Game & 개발방법론

includes.egloos.com

f8 string / wstring 변환

includes.egloos.com/1504676

마지막으로 안시와 유니코드 문자열의 간단한 변환은 vc 에서는 A2W(), W2A() 매크로를 이용하는 방법이 있습니다.
atl 매크로를 이용하지만, 매크로이므로 atl 라이버러리와 링크없이 이용할수있는 장점이 있습니다.

#include <atlcore.h>

void MyTest()
{
    USES_CONVERSION;
    std::string s1("abc");
    std::wstring s2(A2W(s1.c_str()));
    s1 = W2A(s2.c_str());
}

 


출처:
CPP.log

이전 글 string / wstring 변환을 응용해서 utf8 string과 wstring 간의 변환 방법을 알아보자.

mbs_to_wcs와 wcs_to_mbs 함수에 utf8을 지원하는 locale을 설정하면 쉽게 변환할 수 있다.

std::wstring wcs(L"가나다라마바사");
std::string utf8s;

std::locale loc("ko_KR.UTF-8"));
// wstring -> utf8
utf8s = wcs_to_mbs(wcs, loc);
// utf8 -> wstring
wcs = mbs_to_wcs(utf8s, loc);

하지만, 이 방법은 OS의 특성을 탄다. (Windows에는 "ko_KR.UTF-8"이라는 locale이 없다.)
시스템에 의존적이지 않게 만들려면 utf8을 위한 codecvt를 직접 구현해 주어야 한다. boost에는 이미 utf8_codecvt_facet이라는 class가 존재한다. 이미 잘 만들어진 구현이 있기 때문에 직접 구현하지 않고 가져다 쓰도록 하자. 그런데 불행히도 이 소스는 public이 아니고 boost의 몇몇 라이브러리(program_options, serialization)를 위한 구현이기 때문에 바로 사용하기는 힘들다. 그렇다고 방법이 없는 것은 아니다.

우선 boost/detail/utf8_codecvt_facet.hpp와 libs/detail/utf8_codecvt_facet.cpp를 가져 온다. 그리고 나서 utf8_codecvt.h와 utf8_codecvt.cpp 파일을 다음과 같이 만들어 준다.

[utf8_codecvt.h]
#ifndef _UTF8_CODECVT_H_
#define _UTF8_CODECVT_H_

#define BOOST_UTF8_BEGIN_NAMESPACE namespace boost { namespace mylib {
#define BOOST_UTF8_END_NAMESPACE }}
#define BOOST_UTF8_DECL
#pragma warning(push)
#pragma warning(disable : 4100)
#include "utf8_codecvt_facet.hpp"
#pragma warning(pop)
#undef BOOST_UTF8_DECL
#undef BOOST_UTF8_END_NAMESPACE
#undef BOOST_UTF8_BEGIN_NAMESPACE
 
typedef boost::mylib::utf8_codecvt_facet utf8_codecvt;

#endif // _UTF8_CODECVT_H_

[utf8_codecvt.cpp]
#define BOOST_UTF8_BEGIN_NAMESPACE namespace boost { namespace mylib {
#define BOOST_UTF8_END_NAMESPACE }}
#define BOOST_UTF8_DECL
#pragma warning(push)
#pragma warning(disable : 4244)
#pragma warning(disable : 4819)
#pragma warning(disable : 4100)
#include "utf8_codecvt_facet.cpp"
#pragma warning(pop)
#undef BOOST_UTF8_DECL
#undef BOOST_UTF8_END_NAMESPACE
#undef BOOST_UTF8_BEGIN_NAMESPACE

프로젝트에 utf8_codecvt.h와 utf8_codecvt.cpp를 추가하여 사용하면 된다.

std::wstring wcs(L"가나다라마바사");
std::string utf8s;

// new로 생성된 utf8_codecvt를 delete할 필요는 없다.
// locale 내부에서 알아서 delete 해준다.
std::locale loc(std::locale(""), new utf8_codecvt);
// wstring -> utf8
utf8s = wcs_to_mbs(wcs, loc);
// utf8 -> wstring
wcs = mbs_to_wcs(utf8s, loc);
※ 로그인 사용자만 덧글을 남길 수 있습니다.