티스토리 뷰

※ 주의 사항 ※

  • 이 글의 목적은 '지식의 전달'이 아닌 '학습의 기록'입니다.
  • 따라서 제가 이해하는 그대로의 내용이 포함됩니다.
  • 따라서 이 글은 사실과는 다른 내용이 포함될 수 있습니다.

 

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바이트가 됩니다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함