|
|
|
| 2008/10/07 11:40||▲
|
|
|
しばらく更新をサボっていました。しかも、ほとんどセットものであるmbtowc、wctomb、mbstowcsと書いたのに、なぜかwcstombsだけ残っていました。というわけで、今回はwcstombs関数です。といっても、"C"ロケールにしか対応しなければ、やることはmbstowcs関数とほとんど同じです。
#include <stddef.h>
size_t wcstombs(char * __restrict__ s, const wchar_t * __restrict__ pwcs, size_t n) { register char *p = s; for (char *t = p + n; p != t && (*p = (unsigned char)*pwcs) != '\0'; p++, pwcs++) ; return p - s; }
後になって気付いたのですが、ワイド文字の値がUCHAR_MAXより大きい場合はエラーにした方がよいのかもしれません。いや、多分そうすべきなのでしょう。これについては、<wchar.h>ヘッダの実装時に改めて検討しなおすことにしたいと思います。
|
| 2006/06/28 11:43|一般ユーティリティ|TB:0|CM:0|▲
|
|
|
よく似た名前の関数が続きますが、今回は、多バイト文字列からワイド文字列に変換するmbstowcs関数です。例によって、現時点では"C"ロケールにしか対応しませんので、実装は簡単です。
#include <stddef.h>
size_t mbstowcs(wchar_t * __restrict__ pwcs, const char * __restrict__ s, size_t n) { register wchar_t *p = pwcs; for (wchar_t *t = p + n; p != t && (*p = (unsigned char)*s) != L'\0'; p++, s++) ; return p - pwcs; }
この関数は、書き込んだワイド文字数を返しますが、n文字を超えて書き込むことはなく、返却値がnの場合には、終端にナルワイド文字が格納されません。
"C"ロケール以外に対応させるには、内部的にmbtowc関数を呼び出した方がよいのかもしれませんが、全てのライブラリ関数はmbtowc関数を呼び出さないかのように振舞わなければなりませんので、実際にはもう一工夫する必要がありそうです。
|
| 2006/06/19 06:31|一般ユーティリティ|TB:0|CM:0|▲
|
|
|
wctomb関数は、mbtowc関数の逆で、ワイド文字から多バイト文字へかんかんするための関数です。例によって、現時点では"C"ロケールにしか対応しませんので、実装はいたって簡単です。
#include <stddef.h>
int wctomb(char *s, wchar_t wc) { if (s == NULL) return 0; *s = (char)wc; return 1; }
sが空ポインタの場合、多バイト文字がシフトシーケンスに依存する場合は非0を、それ以外は0を返す必要があるので、今回は0を返しています。また、wcがナルワイド文字の場合は、シフトシーケンスを初期状態に戻したりといった仕様がありますが、ここでは関係ないので反映されていません。
ところで、sが指す配列はMB_CUR_MAXバイト以上であることが要求されています。C99より前のバージョンの場合、可変長配列が使えませんので、汎整数式とは限らないMB_CUR_MAXを配列の要素数とすることはできず、代わりにMB_LEN_MAXを使わざるを得ませんでしたが、C99ではMB_CUR_MAXを使うことができます。ただし、実際のところ、どちらが効率がよいかは微妙なところです。
|
| 2006/06/15 10:56|一般ユーティリティ|TB:0|CM:0|▲
|
|
|
今回は多バイト文字からワイド文字に変換するためのmbtowc関数です。mbtowc関数はmblen関数とほとんど変わりません。実際、mblen関数は、
mbtowc(NULL, s, n)
と等価だからです。つまり、mbtowc関数とmblen関数の違いは、変換結果を格納するかどうかの違いでしかありません。それでは実装です。
#include <stddef.h>
int mbtowc(wchar_t *pwc, const char *s, size_t n) { if (s == NULL || *s == '\0' || n == 0) return 0; if (pwc != NULL) *pwc = (unsigned char)*s; return 1; }
現時点では、"C"ロケールにしか対応しない方針ですので、多バイト文字をそのままワイド文字に置き換えています。ここで、(unsigned char)でキャストしているのは、値を0〜UCHAR_MAXにするためです。すなわち、0x80〜0xffの範囲の値に対する対策です。
|
| 2006/06/14 15:37|一般ユーティリティ|TB:0|CM:3|▲
|
|
|
mblen関数は、多バイト文字を構成するバイト数を求めるための関数です。ただし、現在のところ、扱っているのが"C"ロケールだけですので、有効な多バイト文字のバイト数は常に1になります。
この関数の基本的な機能は単純なのですが、付随する機能がいろいろとあります。
まず、引数に空ポインタを渡した場合の動作ですが、多バイト文字がシフトシーケンスに依存する場合は非0を、そうでなければ0を返します。今回の実装では、シフトシーケンスに依存するエンコーディングは使用しませんので、この場合は0を返すことになります。
次に、先頭の1バイトが'\0'の場合にも0を返します。他には、サイズとして0を渡した場合にも0を返すことになります。それでは実装です。
#include <stddef.h>
int mblen(const char *s, size_t n) { if (s == NULL || *s == '\0' || n == 0)   return 0; return 1; }
*sの値をもう少し詳しく見て、有効な文字かどうかを判別してもよいのでしょうが、とりあえずナル文字以外は何でもOKという仕様にしておきます。
|
| 2006/06/13 00:16|一般ユーティリティ|TB:0|CM:0|▲
|
|
|
|
|
ホーム
全記事一覧
<< 前ページ
次ページ >>
|