89. wchar_t
1. 키워드
2. wchar_t
사용하기
wchar_t
는 와이드 문자를 저장하기 위한 자료형이다.
- 보통 영문 알파벳은 1바이트로 표현하지만 유니코드는 2바이트 이상으로 표현하기 때문에
wchar_t
에 저장해야 한다.
- Visual Studio에서는
wchar_t
를 unsigned 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
- 리눅스에서
wprintf
로 wchar_t
문자열을 출력할 때는 %s
대신 %S
를 사용하면 된다.
- C에서 다국어 및 유니코드 처리는 매우 까다로운 분야이다.
- 다국어 지원이 필요한 소프트웨어를 개발한다면 ICU(International Components for Unicode) 같은 전문적인 라이브러리를 검토한다.
References