C言語編 標準ライブラリのリファレンス mbrtoc16

先頭へ戻る

mbrtoc16関数

概要 マルチバイト文字を char16_t型の文字に変換する。
ヘッダ uchar.h
形式 size_t mbrtoc16(char16_t* pc16, const char* s, size_t n, mbstate_t* ps);
引数 pc16 変換結果を受け取るメモリアドレス。受け取らない場合はヌルポインタでも良い。
s 変換対象のマルチバイト文字列。
n 変換する最大バイト数。
ps 変換状態を管理するオブジェクトへのポインタ。またはヌルポインタ。
戻り値 引数s が指すバイトから、引数n で指定したバイト数だけを調べ、それがマルチバイト文字として有効なバイト列であれば、マルチバイト文字を構成するバイト数を返す。それがヌル文字ならば 0 を返す。
マルチバイト文字として有効なバイト列でなければ、-1 を size_t型にキャストした値が返される。
有効なバイト列ではあるが、1つのマルチバイト文字として完結しなかった場合には、-2 を size_t型にキャストした値が返される。
マルチバイト文字のバイトを消費せずに、有効な char16_t の文字を構成する値を得られた場合は、-3 を size_t型にキャストした値が返される。
詳細 引数ps は、マルチバイト文字の並びの現時点までの変換状態を管理しているオブジェクトを指す。引数ps をヌルポインタとした場合は、この関数が内部で持っている mbstate_t オブジェクトを使う。これは、プログラム開始時点で適切に初期化されている。
引数s がヌルポインタの場合、「mbrtoc16(NULL, "", 1, ps)」のように呼び出した場合と同じ意味になる。
バイト列がマルチバイト文字を構成しているものと考え、引数 n で指定したバイト数分だけ調べる。調べた範囲が、有効なマルチバイト文字を構成していれば、それに対応する char16_t の文字の 16ビット値を決定し、その値を引数pc16 で指定した位置へ格納する。引数pc16 がヌルポインタの場合は格納せず処理を終える。
char16_t の文字のエンコーディング形式が UTF-16 であるとすると、1文字を1つの char16_t型の値だけでは表現できないケースがあり得る(サロゲートペア)。この場合、この関数の1回の呼び出しで、前半の 16ビット値だけを得られ、次回、同じ mbstate_tオブジェクトを与えることで、続きの 16ビット値を得られる。続きの 16ビット値を得るときには、マルチバイト文字の新たなバイトを消費することがなく、(size_t)-3 という特別な戻り値を返す。
マルチバイト文字を構成するバイト列が無効であるとき、表現形式エラーが発生し、errnoEILSEQ が格納される。
この関数は、ロケールの LC_CTYPE カテゴリの影響を受ける。
注意 あくまで文字の変換なので、末尾に終端文字(u'\0') は付加されない。
VisualStudio 2015/2017 で確認すると、ネイティブロケールではマルチバイト文字のエンコーディングエラーは Shift_JIS (CP932) であるが、UTF-8 の文字列を渡さなければならないようである。Shift_JIS の文字列を渡すと、エンコーディングエラーになることがある。
使用例
#include <locale.h>
#include <stdio.h>
#include <uchar.h>

int main(void)
{
    // LC_CTYPE をネイティブロケールに変更
    if( setlocale( LC_CTYPE, "" ) == NULL ){
        fputs( "ロケールの設定に失敗しました。\n", stderr );
        return 1;
    }

    const char mbs[] = u8"あいうえお";
    const char* const end = mbs + sizeof(mbs);

    char16_t c16s[32];
    mbstate_t mbstate = {0};
    int mbi = 0;
    int c16i = 0;

    for( ;; ){
        const int result = (int)mbrtoc16( &c16s[c16i], &mbs[mbi], end - &mbs[mbi], &mbstate );
        if( result > 0 ){
            c16i++;
            mbi += result;
        }
        else if( result == 0 ){
            // ヌル文字に到達
            break;
        }
        else if( result == -1 || result == -2 ){
            fputs( "無効なバイト列です。\n", stderr );
            break;
        }
        else if( result == -3 ){
            // char16_t の文字を構成する残りの部分を得た。
            // マルチバイト文字側のバイトは消費していない。
            c16i++;
        }
    }

    for( int i = 0; i < c16i; ++i ){
        printf( "%x\n", c16s[i] );
    }

    return 0;
}

実行結果:

3042
3044
3046
3048
304a
関連 char16_t の文字からマルチバイト文字への変換は、c16rtomb関数で行える。
解説章 第47章


参考リンク



更新履歴

'2018/7/5 新規作成。



標準ライブラリのリファレンス(名前順)のトップページへ

標準ライブラリのリファレンス(ヘッダ別)のトップページへ

C言語編のトップページへ

Programming Place Plus のトップページへ


はてなブックマーク Pocket に保存 Twitter でツイート Twitter をフォロー
Facebook でシェア Google+ で共有 LINE で送る rss1.0 取得ボタン RSS
管理者情報 プライバシーポリシー