티스토리 뷰
※ 주의 사항 ※
- 이 글의 목적은 '지식의 전달'이 아닌 '학습의 기록'입니다.
- 따라서 제가 이해하는 그대로의 내용이 포함됩니다.
- 따라서 이 글은 사실과는 다른 내용이 포함될 수 있습니다.
char 타입
char 타입은 원래 1바이트의 영문자를 나타냅니다. 그러나 만약 char 타입의 배열로 사용한다면, 실제 다음의 예제와 같이 한글이나 한자처럼 1바이트 이상을 차지하는 유니코드를 수용할 수 있습니다.
#include <iostream>
#include <cstring>
int main()
{
char en[] = "Hello world!";
std::cout << "char " << en << std::endl;
std::cout << "입력 문자 : ";
std::cin >> en;
for (int i = 0; en[i]; i++)
{
std::cout << (char)en[i];
}
std::cout << std::endl;
char wc1[] = "한글화 작업";
std::cout << wc1 << std::endl;
int i = 0;
while (wc1[i])
{
std::cout << (char)wc1[i++]; //한 바이트 단위로 문자를 출력해도 유니코드가 출력됨
}
std::cout << std::endl;
const char* wc2 = "한글화 작업";
std::cout << wc2 << ", 문자 크기 : " << strlen(wc2) << std::endl;
return 0;
}
/*
실행 결과
char Hello world!
입력 문자 : 코리아
코리아
한글화 작업
한글화 작업
한글화 작업, 문자 크기 : 11
*/
실행 결과를 보면 "한글화 작업"의 크기가 11바이트로 계산된 것을 확인할 수 있습니다. 윈도우는 한글을 CP(코드 페이지)949라고 하는 유니코드를 사용합니다. CP949에서 한글은 2바이트로 처리합니다. 따라서 "한글화 작업" 내 한글은 하나 당 2바이트로 총 10바이트가 되고, 공백 1바이트가 추가되어 11바이트로 크기가 계산됩니다.
반면 위 예제를 리눅스에서 실행한다면 "한글화 작업"의 크기는 16바이트가 됩니다. 리눅스는 UTF-8이라고 하는 유니 코드를 사용하는데 UTF-8에서 한글은 초성, 중성, 종성으로 나누어 총 3바이트로 환산합니다. 따라서 "한글화 작업" 내 모든 한글은 하나 당 3바이트로 총 15바이트가 되며, 공백 1바이트가 추가되어 16바이트로 크기가 계산됩니다.
wchar_t 타입
윈도우의 경우 wchar_t 타입은 2바이트로 문자를 표현하는 UTF-16을 사용합니다. 반면 리눅스의 경우 wchar_t 타입은 4바이트로 문자를 표현하는 UTF-32를 사용합니다. 아래의 예제를 보겠습니다.
#include <iostream>
#include <locale>
int main()
{
//화면에 정상 출력하려면 운영체제에서 사용하는 유니코드에 맞춰 인코딩 해야 함
#if defined __linux__ || defined __CYGWIN__
setlocale(LC_ALL, "ko_KR.utf8");
std::wcout << L"setlocale(LC_ALL, \"ko_KR.utf8\");" << std::endl;
#elif defined(WIN32)
std::wcout.imbue(std::locale("kor"));
std::wcin.imbue(std::locale("kor"));
std::cout << "std::wcout.imbue(std::locale(\"kor\"));" << std::endl;
#else
setlocale(LC_ALL, "");
std::wcout << L"setlocale(LC_ALL, \"Korean\");" << std::endl;
#endif
wchar_t en[] = L"Hello world!"; //리터럴 문자를 wchar_t 타입으로 만들기 위해 앞에 'L' 붙이기
//wchar_t 타입의 문자를 출력하려면 std::wcout을 사용해야 함
std::wcout << L"wchar_t " << en << L", wchar_t 바이트 크기 : " << sizeof(wchar_t) << std::endl;
std::cout << "문자 입력 : ";
std::wcin >> en; //콘솔로부터 문자를 읽어들일 때 std::wcin 사용
std::cout << "std::cout을 사용하면 '";
//std::cin으로 입력받은 문자열은 UTF-16 또는 UTF-32이므로 std::cout으로는 정상 출력이 불가능
for (int i = 0; en[i]; i++)
{
std::cout << (char)en[i];
}
std::cout << '\'' << std::endl;
std::wcout << L"그러나 std::wcout을 사용하면 '" << en << '\'' << std::endl;
wchar_t wc1[] = L"한글화 작업";
std::wcout << wc1 << std::endl;
int i = 0;
while (wc1[i])
{
std::cout << (char)wc1[i++]; //정상적으로 출력되지 않음
}
std::cout << std::endl;
const wchar_t* wc2 = L"\ud55c\uae00화 작업";
std::wcout << wc2 << L", 문자 크기 : " << wcslen(wc2) << std::endl;
return 0;
}
/*
실행 결과
std::wcout.imbue(std::locale("kor"));
wchar_t Hello world!, wchar_t 바이트 크기 : 2
문자 입력 : 코리아
std::cout을 사용하면 'T촂'
그러나 std::wcout을 사용하면 '코리아'
한글화 작업
\T 뫥
한글화 작업, 문자 크기 : 6
*/
위 예제를 보면 "한글화 작업"의 문자 크기는 6으로 나옵니다. 하지만 이 데이터가 차지하는 메모리 크기를 계산하면 UTF-16을 사용하는 윈도우는 12바이트, UTF-32를 사용하는 리눅스는 24바이트가 됩니다.
'공부 일지 > CPP 공부 일지' 카테고리의 다른 글
C++ | 열거형 (0) | 2021.08.06 |
---|---|
C++ | 묶음 타입(구조체와 공용체) (0) | 2021.08.06 |
C++ | void 타입과 unspecified (0) | 2021.08.06 |
C++ | auto 타입과 decltype 타입 (0) | 2021.08.06 |
C++17 STL | 구조체 형태의 바인딩 (0) | 2021.08.05 |