I'm FanJae.

[System Programming] Windows 에서의 유니코드 본문

System Programming

[System Programming] Windows 에서의 유니코드

FanJae 2024. 8. 30. 22:09
본 내용은 뇌를 자극하는 윈도우즈 시스템 프로그래밍(윤성우 저) 책을 보고 정리한 내용입니다.

개인이 학습한 내용을 정리할 목적으로 게시한 것으로 책의 상세한 내용은 직접 구매하여 확인을 부탁드립니다. 

 

1. 문자셋(Character Sets)의 종류와 특성

① SBCS(Single Byte Character Set)

- 문자를 표현하는데 1바이트를 사용한다.

- 아스키 코드는 SBCS의 종류 중 하나이다.

② MBCS(Multi Byte Character Set)

- 문자를 표현하는데 있어서 동일한 바이트 수를 적용하는 것이 아닌, 다양한 바이트 수를 사용해서 멀티다.

- 한글은 2바이트, 영문은 1바이트를 사용한다.

- 우리나라의 경우 MBCS를 기반으로 문자를 표현한다.

- 안정성의 문제가 발생할 수 있음.

③ WBCS(Wide Byte Character Set)

- 모든 문자를 표현하는데 2바이트 사용

- 유니코드

 

1-1. MBCS 기반의 문자열과 그 문제점

① 예제1

#include <stdio.h>
#include <string.h>
int main(void)
{
    char str[] = "ABC한글"; // 영어 3byte + 한글 4 byte + null 문자 = 8byte
    int size = sizeof(str);
    int len = strlen(str);
    
    printf("배열의 크기 : %d\n",size);
    printf("문자열의 길이 : %d\n",len);
    
    return 0;
}

- ABC한글의 문자열의 길이는 5지만 실제 출력해보면 7이 나온다.

- 한글이라는 글자에서 '한'과 '글'이 각각 2개씩 잡아먹어서 발생하는 문제이다.

 

② 예제2

#include <iostream>
int main(void)
{
    char str[] = "한글입니다";
    int i;
    
    for(i = 0; i < 5; i++)
        fputc(str[i],stdout);
    
    fputs("\n",stdout);
    
    for(i=0; i < 10; i++)
        fputc(str[i],stdout);
    
    fputs("\n",stdout);
    return 0;
}

- 일반적으로 이렇게 프로그래밍을 안한다. (그냥 이해를 위한 예제일 뿐이다)

- 다만 첫번째로 등장하는 for에서 '한'과 '글'을 각각 2문자로 인식했기 때문에, 문제가 발생하는 것이다.

- 문제는 한글을 사용할 때 이러한 형태 때문에 실수할 가능성이 높아진다.

1-2. WBCS 기반의 프로그래밍

① char를 대신하는 wchar_t

- wchar_t는 유니코드를 위한 기본 자료형이다. 

- typedef unsigned short wchar_t;와 같이 선언되어 있다.

- 모든 문자를 2바이트로 처리한다. (NULL 문자도 포함이다.)

② "ABC"를 대신하는 L"ABC"

- L을 붙이는 이유는 유니코드 기반으로 선언을 해준다는 의미이다.

- 와이드 문자열 리터럴이다.

- wchar_t str[] = L"ABC"; 이와 같이 사용한다.

 

1-3. SBCS 기반 함수와 WBCS 기반 함수

#include <stdio.h>
#include <string.h>
int main(void)
{
    wchar_t str[] = L"ABC";
    int size = sizeof(str);
    int len = strlen(str); // strlen (char *)
    
    printf("배열의 크기 : %d\n",size);
    printf("문자열의 길이 : %d\n",len);
    
    return 0;
}

- strlen의 함수 원형은 다음과 같다.

- size_t strlen ( const char * str ); 이다. 즉, wchar_t는 받을 수 없다.

- 즉, 이들은 모두 SBCS 기반 문자열 조작 함수이다.

- 이들을 굳이 SBCS 기반 문자열 함수라고 하는 이유는 '한글'이 개입하는 경우 제대로 표현하지 못하는 점 때문에 그렇다.

- 이들은 각각 WBCS에 대응하는 함수가 존재한다.

 

① wcslen

#include <stdio.h>
#include <string.h>
int main(void)
{
    wchar_t str[] = L"ABC";
    int size = sizeof(str);
    int len = wcslen(str);
    
    printf("배열의 크기 : %d\n",size);
    printf("문자열의 길이 : %d\n",len);
    
    return 0;
}

 

② wprintf

#include <stdio.h>
#include <string.h>
int main(void)
{
    wchar_t str[] = L"ABC";
    int size = sizeof(str);
    int len = wcslen(str);
    
    wprintf(L"배열의 크기 : %d\n",size);
    wprintf(L"문자열의 길이 : %d\n",len);
    
    return 0;
}

- 입출력 함수도 유니코드 버전이 존재한다. 이에 맞게 문자열도 유니코드 방식으로 선언한다.

 

③ wmain

- 일반적으로 C에서 메인에 매개변수를 보내는 경우 이들은 모두 문자열(char *) 형태로 보내진다.

- 이를 유니코드화 해서 받으려면 메인함수도 wmain()으로 바꿔야 한다.

int main(int argc, char* argv[])
int wmain(int argc, wchar_t* argv[])
#include <stdio.h>
#include <string.h>
int wmain(int argc, wchar_t* argv[])
{
    for(int i=1; i<argc; i++)
    {
        fputws(argv[i],stdout);
        fputws(L"\n", stdout);
    }
    return 0;
}

- 이와 같이 하면 전달되는 문자열은 MBCS 기반으로 구성되어 인자로 전달된다.

Comments