본문 바로가기

C++

wchar_t 사용과 관련하여.

[1. 개요]

윈도우 환경에서 wchar_t 에 관련 된 여러 연산 들 중, 아래와 같은 연산 결과가 예상과 다름.

  • iswdigit
  • iswalpha
  • iswalnum

한글 '안' 을 유니코드로 표현하면, 10진수로 50504 이며,

이는 기존 아스키 코드로 표현가능한 숫자, 영문이 아님을 알 수 있지만, 

위 함수들의 결과는 숫자, 알파벳이라고 그 결과를 반환한다.

 

또, wstring 에 대해서, std::wcout 등을 통해 출력해도 정상적으로 문자열이 출력되지 않았음.

 

해결 방법을 알아보던 중, locale 을 제대로 설정하지 않았다는 것을 보았고, 그 밖에 관련된 것들이 아래와 같은데,

  • std::locale() 
  • SetConsoleOutputCP(CP_UTF8);
  • std::locale::global(std::locale(""));
  • std::wcout.imbue(std::locale("kor"));
  • setlocale(LC_CTYPE, "ko-KR.UTF-8");
  • std::setlocale(LC_ALL, "");

윈도우 os 에서 정상적으로 동작하지 않았음.

 

locale 설정하는 것은 맞지만, 결과적으로는 윈도우에서 정상 동작 여부가 보장되지 않는 것으로 보임.

  • 컴파일러를 msvc 로 사용해도, 

리눅스에서는 아래 소스코드가 모두 기대했던 결과가 나왔음.

 

결론은

  • 윈도우라면 알파벳이나 숫자 인지 등에 대한 처리는 직접 구현하는 편이 좋고,
  • 리눅스라면 가볍게 테스트 후 활용 해도 무방한 듯

[2. 코드-1]

#include <iostream>
#include <string>
#include <cstring>
#include <cctype>
#include <cwctype>
#include <clocale>

int main()
{
    const wchar_t* wst = L"안녕하세요A";
    const int len = wcslen(wst);

    std::cout << int(wst[0]) << std::endl;
    std::cout << "isalnum: " << std::isalnum(wst[0]) << std::endl;
    std::cout << "iswalnum: " << std::iswalnum(wst[0]) << std::endl;

    // 이 부분은 리눅스 환경에서만 거의 정상적으로 동작하는 듯.
    const char * loc = setlocale(LC_CTYPE, "ko-KR.UTF-8");
    std::cout << "setlocale" << std::endl;
    if (loc) std::cout << loc << std::endl;
    else std::cout << "fail..." << std::endl;

    std::cout << "isalnum: " << std::isalnum(wst[0]) << std::endl;
    std::cout << "iswalnum: " << std::iswalnum(wst[0]) << std::endl;

    std::cout << int(wst[len-1]) << std::endl;
    std::cout << "isalnum: " << std::isalnum(wst[len-1]) << std::endl;
    std::cout << "iswalnum: " << std::iswalnum(wst[len-1]) << std::endl;

    return 0;
}

[2. 코드-2]

#include <iostream>
#include <string>
#include <cstring>
#include <cctype>
#include <cwctype>
#include <clocale>


int main()
{
    // 시스템 locale 설정을 변경
    // 환경 변수에 따라 자동 설정
    std::setlocale(LC_ALL, "");
    // c++ stream 에 locale 을 설정 한다.
    std::wcout.imbue(std::locale(""));

    std::wcout << std::locale("").name().c_str() << std::endl;
    const wchar_t *wst = L"안녕하세요A";

    std::wcout << wst[0] << " " << int(wst[0]) <<  L"\n";
    std::wcout << wst << L"\n";
    std::wcout.flush();
    return 0;
}

[3. locale 에 관해서...]

'C++' 카테고리의 다른 글

wchar_t 사용에 관하여 [2]  (0) 2025.05.13
std::bind  (0) 2025.04.28
bitfield 사용 시 유의할 점  (0) 2025.04.28
OS 별 select() 함수 사용법  (0) 2025.04.24
구조체 대입 연산  (0) 2025.04.15