C99に対応した標準Cライブラリの実装レポートを行っていきます。

プロフィール 

Author:高木信尚

ホームページ
ブログ

最近の記事 

最近のコメント 

最近のトラックバック 

月別アーカイブ 

カテゴリー 

ブロとも申請フォーム 

この人とブロともになる

ホーム 全記事一覧 << 前ページ 次ページ >>

 

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:0CM: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:0CM: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:0CM: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:0CM: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:0CM:0

ホーム 全記事一覧 << 前ページ 次ページ >>

ブログ内検索 

お勧め書籍 

RSSフィード 

リンク 

このブログをリンクに追加する

Powered By FC2ブログ 

Powered By FC2ブログ
ブログやるならFC2ブログ

Copyright(C) 2006 TAKAGI Nobuhisa All rights reserved.
Powered by FC2ブログ. 無料ホームページ アフィリエイト レンタルサーバー FC2ブログ 一戸建て template designed by 遥かなるわらしべ長者への挑戦.