ICU – International Components for Unicode

이런 저런 이유로 유니코드를 이제 많이 사용하게 되었습니다.


그런데 유니코드 관련 프로그래밍을 하려면… 쩝 기존의 로직과의 호환성 문제나…
라이브러리간의 인코딩 문제로 머리가 아파오기 시작합니다.


Windows는 기본으로 UTF-16 LE를 사용하고 있습니다.
딱 2 bytes의 wchar_t 로 표현되는 BMP 문자만…
인코딩 방법에 따라…
UTF-7, UTF-8, UTF-16, UTF-32, …
왜 이건 통일이 안되는지… 시스템마다 sizeof(wchar_t) 조차도 다르고 C++ 표준 문서에는
wchar_t는 유니코드 문자열을 표현하는데 사용하는 문자 타입 정도로만 정의를 해 둔 상태죠…


그래서 ICU 같은 라이브러리가 필요하게 되었습니다.


[ICU 홈페이지]


ICU 홈페이지의 Download ICU에 가면 ICU4C, ICU4J가 있는데요. 각각 C/C++과 Java를 위한 라이브러리 입니다.
문제는… 내가 원하는 환경에 맞는 빌드가 존재하지 않는다는 것!
소스를 받아도 빌드하려면 아주 번거롭고 필요한 것이 아주아주 많다는 것!!!


그래서 찾다보니 이런 사이트가 있네요.
개인 홈페이지인데…


[sigmoid의 Precompiled ICU 페이지]


많이들 사용하시는 Visual Studio 2010, 2012, 2013용 Precomplied ICU 라이브러리가 제공됩니다.

유니코드 텍스트 파일 읽고 쓰기

메모장으로 가나다라ABCD를 입력하고 다른 이름으로 저장하면서 인코딩을 유니코드로 바꾼뒤에
헥스에디터 등으로 열어보면 BOM이 앞 2바이트에 적혀 있는 것을 볼 수 있습니다.
유니코드로 저장하면 FF FE 이죠…

이런 유니코드 파일을 프로그램에서 처리하려면 어떻게 해야 할까요?

CreateFile()로 열어서 앞 2바이트를 읽어서 BOM을 분석한 후에 이후 바이트를 그에 맞게 읽는다.
가 정답일 겁니다.

귀찮습니다.

그냥 윈도우 유니코드 텍스트 파일 형식을 그냥 쓰고 싶은데…

그럼 아래와 같이 해보세요.

파일을 열 때에 rt나 wt만으로 열지 않고 인코딩을 명시하는 겁니다.
MSDN의 문서에 자세히 설명되어 있습니다.

#include <stdio.h>
#include <locale.h>

int wmain()
{
	setlocale(LC_ALL, ".OCP");
	FILE* fp = nullptr;
	if (_wfopen_s(&fp, L"test.txt", L"wt, ccs=UTF-16LE") != 0)
		return -1;
	fwprintf_s(fp, L"가나다라ABCD");
	fclose(fp);
	fp = nullptr;

	if (_wfopen_s(&fp, L"test.txt", L"rt, ccs=UTF-16LE") != 0)
		return -1;
	wchar_t ttt[1024] = {0};
	fwscanf_s(fp, L" %s ", ttt, 1024);
	fclose(fp);
	fp = nullptr;

	wprintf_s(L"%s\n", ttt);

	if (_wfopen_s(&fp, L"test.txt", L"rb") != 0)
		return -1;

	unsigned char buf[1024] = {0};
	size_t ret = fread_s(buf, 1024, 1, 1024, fp);
	wprintf_s(L"Size: %d bytes\n", (int)ret);
	for (size_t i = 0; i < ret; ++i)
	{
		wprintf_s(L"%02x ", buf[i]);
		if (i % 16 == 15)
			wprintf_s(L"\n");
	}

	fclose(fp);
	fp = nullptr;

	return 0;
}

참 쉽죠잉???