2024. 9. 6. 18:12ㆍ프로그래밍
Unicode 는 문자를 메모리에 저장할 때 어떤 값으로 저장할지 정해둔 코드 체계 중 하나 이다.
Unicode에서 문자 하나를 몇 bit 로 표현하느냐에 따라서 8bit 즉 1byte씩 문자에 따라 여러 bytes로 표현될 수 있는, 가변 길이로 표현하는 것이 utf-8이고, 문자당 32bit 고정 길이로 표현하는 것이 utf-32 이다.
utf-8 포맷으로 저장된 아래와 같은 cpp 소스가 있을 때, std::string str("가나다") 와 같이 작성하면, str 에 utf-8 로 "가나다" 가 저장되게 되고, str.size() 해보면 9 가 나온다. 이는 한글 unicode경우 utf-8 형식에서는 글자당 3 bytes 차지하기 때문이다.
std::setlocale(LC_ALL, ""); // setlocale 하지 않으면 unicode깨져서 출력됨
std::string str("가나다");
wprintf(L"str size = %lu\n", str.size());
한글 "가나다" 문자열의 문자수가 정확히 3이 되도록 하자면, utf-8 이 아닌 utf-32 의 고정길이 포맷을 사용해야하고, 이러한 32bit utf-32 문자하나는 wchar 변수에 저장될 수 있고, 문자열은 std::wstring 같은 곳에 저장될 수 있다. utf-8 문자열을 가지는 std::string은 utf-32인 문자열을 가지는 std::wstring 으로 변경할 수 있다. 아래와 같이 std 라이브러리의 wstring_convert 를 사용하면 std::string을 std::wstring으로 변환 가능하다. wstr.size() 는 예상대로 3이 된다.
using convert_typeX = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_typeX, wchar_t> converterX;
std::wstring wstr = converterX.from_bytes(str.c_str()); // std::string str
wprintf(L"wstr size = %lu\n", wstr.size());
아래와 같이 utf-32형태의 wchar 한자씩 출력하고, 해당 문자의 utf-8 유니코드 3 bytes씩 출력해 보면,
for (int i =0; i < wstr.size(); i++) {
wprintf(L"%d :%lc %u %u %u\n", i, wstr[i],
(uint8_t) str[i*3+0], (uint8_t) str[i*3+1], (uint8_t) str[i*3+2]);
}
0 :가 234 176 128
1 :나 235 130 152
2 :다 235 139 164
위와 같이 출력되는데, 아래 사이트를 통해 utf-8 유니코드 값이 일치하는 것을 확인할 수 있다.
https://jjeong.tistory.com/696
나아가 utf-32 코드를 아래와 같이 출력해 보면,
uint32_t* ptr = (uint32_t*)wstr.c_str();
for (int i =0; i < 3; i++) {
wprintf(L"%d : %lc %X\n", i, ptr[i], (uint32_t) ptr[i]);
}
0 :가 AC00
1 :나 B098
2 :다 B2E4
위와 같이 utf-32 유니코드를 확인 할 수 있다.
참고로 utf-32의 std::wstring에서 utf-8의 std::string으로 변환은 아래와 같이 하면 된다.
using convert_typeX = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_typeX,wchar_t> converterX;
std::string str = converterX.to_bytes(wstr); // std::wstring wstr
그리고 주의점은 wprintf() 나 printf()는 동시에 사용할 수 없으며, 만약 섞어 사용시 프로그램상 둘중 먼저 사용한 쪽만 정상적으로 출력된다. 예를 들어 printf()를 먼저 사용했다면 이후 사용된 wprintf()의 출력은 화면에 나타나지 않게 된다.
'프로그래밍' 카테고리의 다른 글
OpenVINO int8 모델 변환 2024.5 버전 (0) | 2024.12.14 |
---|---|
C 혹은 C++ 에서 실행중인 파일 경로 구하기 (0) | 2024.08.27 |
Python과 C 혹은 C++ 연동 사용하기 (0) | 2024.08.27 |
ChatGPT의 sample code 오류 (0) | 2023.03.08 |