본문 바로가기

프로그래밍/MAC OS

macOS Xcode 에서 한글입력 특이사항

반응형

간단하게 이름과 나이를 입력받아 출력해 주는 C 프로그램이다. 간단히 실행한 내용은 다음과 같다.

이름을 입력하세요. : 홍길녀
나이를 입력하세요. : 18
나의 이름은 홍길녀 이고, 나이는 18 입니다.
이름의 바이트 길이는 24.
이름[00:03] = e1 84 92 = ᄒ
이름[03:06] = e1 85 a9 = ᅩ
이름[06:09] = e1 86 bc = ᆼ
이름[09:12] = e1 84 80 = ᄀ
이름[12:15] = e1 85 b5 = ᅵ
이름[15:18] = e1 86 af = ᆯ
이름[18:21] = e1 84 82 = ᄂ
이름[21:24] = e1 85 a7 = ᅧ

리눅스 등에서 일반적으로 utf-8 의 한글은 한음절이 3바이트로 인코딩되는데, 위 결과를 보면, 자모 하나 당 3바이트로 인코딩이 되어 (NFD정규화) 있다. 홍길녀 3음절이, ㅎㅗㅇㄱㅣᆯㄴㅕ 8개 자모로 분리되어 (첫가끝) 각 자모당 3바이트씩, 총 24바이트를 사용하고 있다.

그런데, 위 실행내용은 xcode 의 output 창에서 입력하여 나온 결과이고, 터미널에서 실행한 결과는 달랐다.

➜  Debug git:(main) ✗ ./C-hangul-test 
이름을 입력하세요. : 홍길녀
나이를 입력하세요. : 16
나의 이름은 홍길녀 이고, 나이는 16 입니다.
이름의 바이트 길이는 9.
이름[00:03] = ed 99 8d = 홍
이름[03:06] = ea b8 b8 = 길
이름[06:09] = eb 85 80 = 녀

리눅스와 같이 음절 하나가 3바이트로 인코딩되어 (NFC정규화) 홍길녀 3글자를 저장하는데, 9바이트를 사용하고 있다. 

 

테스트한 프로그램의 소스는 다음과 같다. name 버퍼의 내용을 보여주는 부분을 제외하면, 아주 기초적인 입출력 프로그램이다.

//
//  main.c
//  C-hangul-test
//
//  Created by andrew_mac on 2023/02/28.
//

#include <stdio.h>
#include <string.h>

int main(int argc, const char * argv[]) {
    
    char name[30] = { 0, };
    char buff[10] = { 0, };
    int age;
    int i;
    
    printf("이름을 입력하세요. : ");
    scanf("%s", name);
    
    printf("나이를 입력하세요. : ");
    scanf("%d", &age);
    
    getchar();
    
    printf("나의 이름은 %s 이고, 나이는 %d 입니다.\n", name, age);
    printf("이름의 바이트 길이는 %ld.\n", strlen(name));
    
    /*
    for (i = 0 ; i < strlen(name); i += 3) {
        buff[0] = name[i];
        buff[1] = name[i+1];
        buff[2] = name[i+2];
        buff[3] = 0;
        printf("이름[%02d:%02d] = %02x %02x %02x = %s \n", i, i+3, 0xFF & buff[0], 0xFF & buff[1], 0xFF & buff[2], buff);
    }
     */
    for (i = 0 ; i < strlen(name); ) {
        unsigned char ch = name[i];
        int len = 1;
        if (ch & 0x80) {
            if ((ch & 0xE0) == 0xC0) {
                len = 2;
            } else if ((ch & 0xF0) == 0xE0) {
                len = 3;
            } else if ((ch & 0xF8) == 0xF0) {
                len = 4;
            }
        }
        printf("이름[%02d:%02d] = ", i, i+len);
        for (int j = 0; j < len; j++) {
            printf("%02x ", 0xFF & name[i+j]);
        }
        printf("= ");
        printf("%.*s\n", len, &name[i]);
       
        i += len;
    }
    
    return 0;
}

 

728x90