이전 UTF8 한글 문자열을 첫가끝 낱자(자소)로 분해하기에서 다룬 한글 완성자를 자소로 분해하는 기능의 역기능을 구현해봤다. 자소를 다시 한글 완성자로 조합하는 것이다. 이전에 다뤘던 코드의 일부가 포함되어 있다.
#include
#include
#include
#include
#include "unistr.h"
#include "normlzr.h"
#include "unorm.h"
#include "bytestream.h"
using namespace std;
int decompose(const char* text, wchar_t* wcs_buf, uint buf_size)
{
// UTF-8 to UCS4
UnicodeString str = UnicodeString::fromUTF8(StringPiece(text));
// UCS4 to NFD
UnicodeString result;
UErrorCode status = U_ZERO_ERROR;
Normalizer::normalize(str, UNORM_NFD, 0, result, status);
if (U_FAILURE(status)) {
cerr << "can't decompose a UTF8 string, " << status << ": " << u_errorName(status) << endl;
return -1;
}
result.toUTF32((UChar32*) wcs_buf, buf_size, status);
return 0;
}
int compose(wchar_t* wcs, uint wcs_len, char* buf, uint buf_size)
{
// UCS4 to NFC
UnicodeString str = UnicodeString::fromUTF32((UChar32*) wcs, wcs_len);
UnicodeString result;
UErrorCode status = U_ZERO_ERROR;
Normalizer::normalize(str, UNORM_NFC, 0, result, status);
if (U_FAILURE(status)) {
cerr << "can't compose a UTF8 string, " << status << ": " << u_errorName(status) << endl;
return -1;
}
string temp;
StringByteSink sink(&temp);
result.toUTF8(sink);
strcpy(buf, temp.c_str());
return 0;
}
int main(void)
{
const char* text = "한글";
wchar_t wcs_buf[1024];
char new_text[1024];
decompose(text, wcs_buf, sizeof (wcs_buf));
for (uint i = 0; wcs_buf[i] != 0; ++i) {
cout << "wcs_buf[" << i << "]=0x" << hex << (int) wcs_buf[i] << endl;
}
cout << endl;
int wcs_len = wcslen(wcs_buf);
compose(wcs_buf, wcs_len, new_text, sizeof (new_text));
cout << new_text << endl;
return 0;
}
조심할 것은 UErrorCode 타입 변수의 사용이다. normalize() 함수를 호출하기 전에 status를 초기화해야 함수가 제대로 동작한다. status를 초기화하지 않고 사용하면 어떤 경우에는 제대로 동작하고, 어떤 경우에는 오동작하는 이상한 증상이 나타난다.