ja_JP ロケールにおける wctype(3)/iswctype(3), wctrans(3)/towctrans(3)
wctype(3) は引数として渡された名前に対応した property を返し,これを利用して iswctype(3) である文字がその property を持っているかどうか判定する.どんな property があるかはロケールに依存しているが,alnum, alpha, blank 等の全てのロケールで使えるものもある.これらの property による判定はそれぞれよく知られている isalnum(3), isalpha(3), isblank(3) 等と同じ.
wctrans(3)/towctrans(3) は似たようなインターフェイスで文字の変換を行う.全てのロケールで使えるものは tolower, toupper で,それぞれ tolower(3), toupper(3) にあたる.
で,日本の ja_JP ロケールにおいては /usr/share/i18n/locales/ja_JP を見てみると wctype(3) に渡せる名前として
- jspace
- jhira
- jkata
- jkanji
- jdigit
が使え,wctrans(3) には
- tojhira
- tojkata
が使えるみたい.
とりあえず手元の Linux 環境と ideone で以下のコードが意図した通りに動いたけど,どれくらい広く利用可能なのか,*BSD 系でも同様に動作するのかは知らない.
http://ideone.com/7kWcM
#include <stdio.h> #include <stdlib.h> #include <locale.h> #include <wchar.h> #include <wctype.h> static void sample_wctype(const wchar_t *str, const char *name) { const wctype_t wc = wctype(name); if (wc == (wctype_t)0) { fprintf(stderr, "wctype(%s) is not supported in this locale\n", name); return; } const size_t len = wcslen(str); size_t i; for (i = 0; i < len; i++) { wprintf(L"is%s? %lc => %d\n", name, str[i], iswctype(str[i], wc)); } } static void sample_wctrans(const wchar_t *str, const char *name) { const wctrans_t wct = wctrans(name); if (wct == (wctrans_t)0) { fprintf(stderr, "wctrans(%s) is not supported in this locale\n", name); return; } const size_t len = wcslen(str); size_t i; for (i = 0; i < len; i++) { wprintf(L"%s %lc => %lc\n", name, str[i], towctrans(str[i], wct)); } } int main(void) { if (setlocale(LC_ALL, "ja_JP.UTF-8") == NULL) { fputs("setlocale failed\n", stderr); return 1; } const wchar_t str[] = L"廾ゃヵ"; sample_wctype(str, "jkata"); sample_wctype(str, "jkanji"); sample_wctrans(str, "tojkata"); return 0; }