文字対応の操作のための API のうち、日本語ロケールの文字集合の処理に有効な API を表 3-1、表 3-2 に示します。その他にも API が用意されています。詳しくはマニュアルページ (towctrans(3C)、wctrans(3C)、wctrans_ja(3C) など) を参照してください。
表 3-1 文字対応 API その 1|
XPG で規定されるインタフェース名 |
作用 |
|---|---|
|
towupper (wc) |
ワイド文字 wc に対応する大文字ワイド文字表現を返す。なければ wc をそのまま返す |
|
towlower (wc) |
ワイド文字 wc に対応する小文字ワイド文字表現を返す。なければ wc をそのまま返す |
|
towctrans (wc, wctrans("タグ名")) |
タグ名 に基づいてワイド文字 wc に対応したワイド文字表現を返す。なければ wc をそのまま返す |
|
wctrans ("タグ名") |
towctrans () で使う、タグ名に対応する値を返す。タグ名として以下が使用できる。 "tolower", "toupper" |
表 3-2 文字分類 API その 2
|
日本語 Solaris で拡張されたインタフェース名 |
作用 |
|---|---|
|
wctrans("タグ名") |
towctrans() で使う、タグ名に対応する値を返す。Solaris では日本語ロケールにおいて以下をタグ名として使用できる |
|
|
"tojhira" "tojkata" "tojisx0208" "tojisx0201" |
日本語文字対応の API を用いたプログラム例を 2 つ紹介します。使用する場合には wchar.h、wctype.h ヘッダファイルを取り込むこと、また setlocale() を処理の最初の段階で呼び出して動作ロケールを適切に設定することが必要です。
例 3-1 では、入力ファイル中に存在する JIS X 0201 かな文字 (半角カナ) を JIS X 0208 かな文字に変換するフィルタを紹介します。既存のアプリケーション・ネットワークの中には、規約上、または実装上の制限により JIS X 0201 かな文字を使用したデータ通信ができないものがあります。そのような環境に対しては通信に先立ち、JIS X 0201 かな文字を JIS X 0208 かな文字に変換するなど入力ファイルの加工が必要です。この例では、入力ファイルを 1 行ずつワイド文字列として読み込み、各ワイド文字を towctrans() で変換しています。
sun% cat my_kanato208.c
/*
* Read lines from a file and convert JIS X 0201 kana
* characters to the correspondent ones in JIS X 0208
* set. This will stop processing if the input file
* reaches EOF. It is assumed that each line has
* at most BUFSIZ -1 wide char length.
*
* Actual processing is done by my_kanato208(), which
* does the followings.
* 1. Get the length of wide string.
* 2. Convert each wide char from the top
* of the string by applying towctrans().
* (The return value of towctrans() will be
* the same if there's no correspondent char.)
* 3. Write the correspondent wide char to
* original string.
*/
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
#include <wctype.h>
static void my_kanato208(wchar_t *);
int
main(int argc, char *argv[])
{
wchar_t buf[BUFSIZ];
setlocale(LC_ALL, "");
while (fgetws(buf, BUFSIZ, stdin) != (wchar_t *)NULL) {
my_kanato208(buf);
fprintf(stdout, "%S",buf);
}
return (0);
}
static void
my_kanato208(wchar_t *wcp)
{
size_t wstr_len;
wint_t retval;
int index;
wstr_len = wcslen(wcp);
for (index = 0; index < wstr_len; index++) {
retval = towctrans((wint_t)wcp[index],
wctrans("tojisx0208"));
wcp[index] = retval;
}
}
sun% cat file3
新しいシステム*は現在のネットワーク環境を変えることなく
インターネット*とのシームレス*な接続を可能にします。また
セキュリティ*の問題も新しい認証テクノロジー*を用いることで
アドミニストレータ*の負担を減らしています。
sun% cc -o my_kanato208 my_kanato208.c
sun% cat file3 | ./my_kanato208
新しいシステム*は現在のネットワーク*環境を変えることなく
インターネット*とのシームレス*な接続を可能にします。また
セキュリティ*の問題も新しい認証テクノロジー*を用いることで
アドミニストレータ*の負担を減らしています。
* の部分のカタカナは、半角カタカナになります。
例 3-2 は wcstol() の拡張例です。現在の Solaris が提供する日本語ロケールでは、JIS X 0208 文字集合で表された数値文字列に対して、直接 wcstol() を呼び出すことができません。そこで、数値文字列をワイド文字列データとして読み込み、towctrans() で対応する JIS X 0201 文字に変換し、wcstol() を呼び出しています。
sun% cat my_wcstol.c
/*
* Read lines from a file and convert tokenized
* wide char string to long integer.
* Conversion will stop if the input file reaches
* EOF, and output the sum of input integers.
* It is assumed that each line has at most
* BUFSIZ - 1 wide char length.
*
* Actual conversion is done by my_wcstol(), which
* does the followings.
* 1. Get the length of wide char string.
* 2. Convert each wide char from the top
* of the string by applying towctrans().
* The correspondent JIS X 0201 wide char value
* will be gotten for each JIS X 0208 digit chars
* in the string.
* (The return value of towctrans() will be
* the same if there's no correspondent char.)
* 3. Write the correspondent wide char to
* original string.
* 4. Call wcstol() with the converted wide string.
*/
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
#include <wtype.h>
#include <errno.h>
#define WRET L'¥n'
static long my_wcstol(wchar_t *, wchar_t **, int);
int
main(int argc, char *argv[])
{
wchar_t buf[BUFSIZ];
wchar_t *headp, *nextp;
long retval, total;
setlocale(LC_ALL, "");
total = retval = 0;
while (fgetws(buf, BUFSIZ, stdin) != (wchar_t *)NULL) {
headp = buf;
while (headp != (wchar_t *)NULL) {
errno = 0;
retval = my_wcstol(headp, 0);
if (errno != 0) {
if (nextp[0] == WRET) {
break;
} else {
perror("my_wcstol()");
exit (-1);
}
}
fprintf(stdout, "retval = [%ld]¥n", retval);
total += retval;
headp = nextp;
}
}
fprintf(stdout, "Total = %ld.¥n", total);
return (0);
}
static long
my_wcstol(wchar_t *wcp, wchar_t **endp, int base)
{
size_t wstr_len;
wint_t retval;
int index;
long ret_val;
wstr_len = wcslen(wcp);
for (index = 0; index < wstr_len; index++) {
retval = towctrans((wint_t)wcp[index], wctrans("tojisx0201"));
wcp[index] = (wchar_t)retval;
} ret_val = wcstol((const wchar_t *)wcp, endp, base);
return (ret_val);
}
sun% cat file4
343 34534 12
345345 345345
39857 398 5834589
sun% cc -o my_wcstol my_wcstol.c
sun% ./my_wcstol < file4
retval = [343]
retval = [34534]
retval = [12]
retval = [345345]
retval = [345345]
retval = [39857]
retval = [398]
retval = [5834589]
Total = 6600423.