Software Workshop

이전 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를 초기화하지 않고 사용하면 어떤 경우에는 제대로 동작하고, 어떤 경우에는 오동작하는 이상한 증상이 나타난다.