웬디의 기묘한 이야기

글 작성자: WENDYS
반응형

convert ansi string to unicode string and utf-8 string

c/c++에서 ansi string과 unicode string, utf-8 string을 상호 변환하기 위해서는 간단한 대입으로는 불가능합니다. 예전에 소개해드렸던 std::string.assign 방법으로 1byte의 문자열인 경우에만 지원이 되게 되어 제가 만들어서 사용 중인 방법을 소개해드립니다. 쉽게 처리가 되면 참으로 좋겠지만 아래처럼 하면 에러가 나게 됩니다.

그렇기 때문에 string 관련 함수는 따로 만들어놓고 두고두고 사용하는 게 좋습니다.
어떻게 사용하면 좋을지 한번 보겠습니다.
아래 샘플들을 이용하여 편안하고 멋진 개발 하세요 :)

 

convert ansi to unicode string

함수 형태를 변경하여 std::string이 아닌 char* -> wchar_t* 형태를 바꿀 때도 마찬가지로 사용할 수 있습니다.

//
// convert_ansi_to_unicode_string.
//

DWORD convert_ansi_to_unicode_string(
    __out std::wstring& unicode,
    __in const char* ansi,
    __in const size_t ansi_size
    ) {

    DWORD error = 0;

    do {

        if ((nullptr == ansi) || (0 == ansi_size)) {
            error = ERROR_INVALID_PARAMETER;
            break;
        }

        unicode.clear();

        //
        // getting required cch.
        //

        int required_cch = ::MultiByteToWideChar(
                                CP_ACP,
                                0,
                                ansi, static_cast<int>(ansi_size),
                                nullptr, 0
                                );

        if (0 == required_cch) {
            error = ::GetLastError();
            break;
        }

        unicode.resize(required_cch);

        //
        // convert.
        //

        if (0 == ::MultiByteToWideChar(
                    CP_ACP,
                    0,
                    ansi, static_cast<int>(ansi_size),
                    const_cast<wchar_t*>(unicode.c_str()), static_cast<int>(unicode.size())
                    )) {
            error = ::GetLastError();
            break;
        }

    } while (false);

    return error;
}
  

 

convert unicode to ansi string

함수 형태를 변경하여 std::string이 아닌 wchar_t* -> char* 형태를 바꿀 때도 마찬가지로 사용할 수 있습니다.

//
// convert_unicode_to_ansi_string.
//

DWORD convert_unicode_to_ansi_string(
    __out std::string& ansi,
    __in const wchar_t* unicode,
    __in const size_t unicode_size
    ) {

    DWORD error = 0;

    do {

        if ((nullptr == unicode) || (0 == unicode_size)) {
            error = ERROR_INVALID_PARAMETER;
            break;
        }

        ansi.clear();

        //
        // getting required cch.
        //

        int required_cch = ::WideCharToMultiByte(
                                CP_ACP,
                                0,
                                unicode, static_cast<int>(unicode_size),
                                nullptr, 0,
                                nullptr, nullptr
                                );

        if (0 == required_cch) {
            error = ::GetLastError();
            break;
        }

        //
        // allocate.
        //

        ansi.resize(required_cch);

        //
        // convert.
        //

        if (0 == ::WideCharToMultiByte(
                    CP_ACP,
                    0,
                    unicode, static_cast<int>(unicode_size),
                    const_cast<char*>(ansi.c_str()), static_cast<int>(ansi.size()),
                    nullptr, nullptr
                    )) {
            error = ::GetLastError();
            break;
        }

    } while (false);

    return error;
}
  

 

convert unicode to utf8 string

함수 형태를 변경하여 std::string이 아닌 wchar_t* -> char* (utf-8) 형태를 바꿀 때도 마찬가지로 사용할 수 있습니다.

//
// convert_unicode_to_utf8_string
//

DWORD convert_unicode_to_utf8_string(
    __out std::string& utf8,
    __in const wchar_t* unicode,
    __in const size_t unicode_size
    ) {

    DWORD error = 0;

    do {

        if ((nullptr == unicode) || (0 == unicode_size)) {
            error = ERROR_INVALID_PARAMETER;
            break;
        }

        utf8.clear();

        //
        // getting required cch.
        //

        int required_cch = ::WideCharToMultiByte(
                                CP_UTF8,
                                WC_ERR_INVALID_CHARS,
                                unicode, static_cast<int>(unicode_size),
                                nullptr, 0,
                                nullptr, nullptr
                                );

        if (0 == required_cch) {
            error = ::GetLastError();
            break;
        }

        //
        // allocate.
        //

        utf8.resize(required_cch);

        //
        // convert.
        //

        if (0 == ::WideCharToMultiByte(
                    CP_UTF8,
                    WC_ERR_INVALID_CHARS,
                    unicode, static_cast<int>(unicode_size),
                    const_cast<char*>(utf8.c_str()), static_cast<int>(utf8.size()),
                    nullptr, nullptr
                    )) {
            error = ::GetLastError();
            break;
        }

    } while (false);

    return error;
}
  

 

convert utf8 to unicode string

함수 형태를 변경하여 std::string이 아닌 char* (utf-8) -> wchar_t* 형태를 바꿀 때도 마찬가지로 사용할 수 있습니다.

//
// convert_utf8_to_unicode_string
//

DWORD convert_utf8_to_unicode_string(
    __out std::wstring& unicode,
    __in const char* utf8,
    __in const size_t utf8_size
    ) {

    DWORD error = 0;

    do {

        if ((nullptr == utf8) || (0 == utf8_size)) {
            error = ERROR_INVALID_PARAMETER;
            break;
        }

        unicode.clear();

        //
        // getting required cch.
        //

        int required_cch = ::MultiByteToWideChar(
            CP_UTF8,
            MB_ERR_INVALID_CHARS,
            utf8, static_cast<int>(utf8_size),
            nullptr, 0
        );
        if (0 == required_cch) {
            error = ::GetLastError();
            break;
        }

        //
        // allocate.
        //

        unicode.resize(required_cch);

        //
        // convert.
        //

        if (0 == ::MultiByteToWideChar(
                    CP_UTF8,
                    MB_ERR_INVALID_CHARS,
                    utf8, static_cast<int>(utf8_size),
                    const_cast<wchar_t*>(unicode.c_str()), static_cast<int>(unicode.size())
                    )) {
            error = ::GetLastError();
            break;
        }

    } while (false);

    return error;
}
  

 

일반적인 개발 시에는 ansi string과 unicode string에 대한 변환만 사용하겠지만, 만약 웹과 통신이 필요한 경우 utf-8 string을 변환해야 할 수 있게 됩니다. 필요할 때 언제든지 사용할 수 있도록 위 네 가지 정도는 자신만의 라이브러리화 하여 사용하는 것을 추천드립니다.

 

use sample

사용법 샘플을 빼먹을뻔했네요! 사용법 어렵지 않아요 아래와 같이 사용하면 됩니다.

만약 ansi string을 utf-8로 변환하기 위해선 ansi string -> unicode string -> utf-8 string의 변환 과정을 거치면 됩니다.

int main()
{
    
    {
        //
        // convert_ansi_to_unicode_string
        //

        std::wstring unicode = L"";
        std::string ansi = "ansi string";

        convert_ansi_to_unicode_string(unicode, ansi.c_str(), ansi.size());

        std::wcout << unicode.c_str() << std::endl;
    }

    {
        //
        // convert_unicode_to_ansi_string
        //

        std::wstring unicode = L"unicode string";
        std::string ansi = "";

        convert_unicode_to_ansi_string(ansi, unicode.c_str(), unicode.size());

        std::cout << ansi.c_str() << std::endl;
    }

    {
        //
        // convert_unicode_to_utf8_string
        //

        std::wstring unicode = L"unicode string";
        std::string utf8 = "";

        convert_unicode_to_utf8_string(utf8, unicode.c_str(), unicode.size());

        std::cout << utf8.c_str() << std::endl;

        //
        // convert_utf8_to_unicode_string
        //

        std::wstring unicode_2 = L"";

        convert_utf8_to_unicode_string(unicode_2, utf8.c_str(), utf8.size());

        std::wcout << unicode_2.c_str() << std::endl;
    }

    system("pause");
}
  

 

sample download

convert_string.zip
0.00MB

반응형