Skip to content

89. wchar_t


1. 키워드

  • 와이드 문자(Wide Character)


2. wchar_t 사용하기

  • wchar_t는 와이드 문자를 저장하기 위한 자료형이다.
  • 보통 영문 알파벳은 1바이트로 표현하지만 유니코드는 2바이트 이상으로 표현하기 때문에 wchar_t에 저장해야 한다.
  • Visual Studio에서는 wchar_tunsigned short 타입으로 정의하고 있고, GCC에서는 4바이트로 정의하고 있다.
  • 단, GCC에서 -fshort-wchar 옵션을 사용하면 wchar_t를 2바이트로 사용할 수 있다.


  • wchar_t 문자와 문자열은 다음과 같이 ‘’(따옴표) 앞에 L을 붙여서 표현한다.


wchar_t wc1 = L'a';

wchar_t *ws1 = L"Hello, world!"; // 와이드 문자열은 L을 붙임
wchar_t *ws2 = L"안녕하세요.";


  • 다음과 같이 wchar_t 문자열은 w가 붙은 함수를 사용해야 한다.
  • 이런 함수들은 wchar.h 헤더 파일에 선언되어 있다.


#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <wchar.h>

int main()
{
    wchar_t ws1[20];
    wscanf(L"%s", ws1);
    wprintf(L"%s\n", ws1);

    // 두 번째 인수에는 wchar_t 문자열의 문자 개수를 구해서 넣어줌
    swprintf(ws1, sizeof(ws1) / sizeof(wchar_t), L"%s", L"Hello, world!");

    FILE *fp = _wfopen(L"hello.txt", L"w+");
    // _wfopen 함수는 표준이 아니므로 리눅스에서는 사용할 수 없음
    // 리눅스에서는 fopen 함수 사용
    // FILE *fp = fopen("hello.txt", "w+");

    // 리눅스에서는 %s 대신 %S 사용
    wchar_t ws2[20];
    wchar_t ws3[20];
    fwprintf(fp, L"%s", L"C Language");
    rewind(fp);
    fwscanf(fp, L"%s %s", ws2, ws3);
    wprintf(L"%s %s\n", ws2, ws3);

    rewind(fp);
    fputws(L"Wide Character", fp);
    rewind(fp);
    fgetws(ws2, 20, fp);
    wprintf(L"%s\n", ws2);

    rewind(fp);
    fputwc(L'X', fp);
    rewind(fp);
    wint_t wc1 = fgetwc(fp);
    putwchar(wc1);

    fclose(fp);

    return 0;
}

// Hello (입력)
// Hello
// C Language
// Wide Character
// X


  • swprintf 함수는 swprintf(ws1, sizeof(ws1) / sizeof(wchar_t), L”%s”, L”Hello, world!”);와 같이 버퍼와 함께 wchar_t 문자열의 문자 개수를 넣으면 된다.
  • 여기서 wchar_t ws1[20];일 때 sizeof(ws1)만 지정하면 wchar_t 크기가 2바이트이므로 40이 나온다.
  • 따라서 sizeof(ws1)sizeof(wchar_t)로 나누어서 문자 개수를 구하도록 만들어야 한다.
  • _wfopen 함수는 표준이 아니며 Visual Studio에서만 사용할 수 있고 리눅스에서는 사용할 수 없다.


  • wchar_t 문자열 처리 함수는 str 대신 wcs로 시작한다.
  • 예를 들어 strcpy의 와이드 문자 버전은 wcscpy이다.


#define _CRT_SECURE_NO_WARNINGS
#include <wchar.h>

int main()
{
    wchar_t ws1[20] = L"Hello, world!";
    wchar_t ws2[20];

    wprintf(L"%d\n", wcslen(ws1));

    // 리눅스에서는 %s 대신 %S 사용
    wcscat(ws1, L"123");
    wprintf(L"%s\n", ws1);

    wcscpy(ws2, ws1);
    wprintf(L"%s\n", ws2);

    wprintf(L"%d\n", wcscmp(ws1, ws2));

    wchar_t *ptr = wcschr(ws1, L'o');
    wprintf(L"%s\n", ptr);

    ptr = wcsrchr(ws1, L'l');
    wprintf(L"%s\n", ptr);

    ptr = wcsstr(ws1, L"wor");
    wprintf(L"%s\n", ptr);

    wchar_t ws3[20] = L"The Little Prince";
    wchar_t *next;
    ptr = wcstok(ws3, L" ", &next); // next에는 다음번에 자를 문자열의 포인터가 들어감

    while (ptr != NULL)
    {
        wprintf(L"%s\n", ptr);
        ptr = wcstok(NULL, L" ", &next);
    }

    return 0;
}

// 13
// Hello, world!123
// Hello, world!123
// 0
// o, world!123
// ld!123
// world!123
// The
// Little
// Prince


  • 리눅스에서 wprintfwchar_t 문자열을 출력할 때는 %s 대신 %S를 사용하면 된다.
  • C에서 다국어 및 유니코드 처리는 매우 까다로운 분야이다.
  • 다국어 지원이 필요한 소프트웨어를 개발한다면 ICU(International Components for Unicode) 같은 전문적인 라이브러리를 검토한다.

References