Namespaces
Variants

c16rtomb

From cppreference.net
ヘッダーで定義 <uchar.h>
size_t c16rtomb ( char * restrict s, char16_t c16, mbstate_t * restrict ps ) ;
(C11以降)

可変長16ビットワイド文字表現(通常はUTF-16)から、単一のコードポイントをそのナローマルチバイト文字表現に変換します。

s が null ポインタではなく、かつ c16 が有効な可変長エンコーディングのコードポイントの最後の16ビットコード単位である場合、この関数はそのコードポイントのマルチバイト文字表現を格納するために必要なバイト数(シフトシーケンスを含み、現在のマルチバイト変換状態 * ps を考慮して)を決定し、マルチバイト文字表現を s が指す先頭要素の文字配列に格納し、必要に応じて * ps を更新します。この関数によって書き込まれるバイト数は最大で MB_CUR_MAX です。

s がヌルポインタの場合、この呼び出しは内部バッファ buf に対する c16rtomb ( buf, u ' \0 ' , ps ) と等価です。

c16 がナルワイド文字 u ' \0 ' である場合、初期シフト状態を復元するために必要なシフトシーケンスに続けてナルバイトが格納され、変換状態パラメータ * ps は初期シフト状態を表すように更新されます。

c16 が16ビットワイド文字表現の最終コード単位でない場合、配列 s が指す先には書き込まれず、 * ps のみが更新されます。

マクロ __STDC_UTF_16__ が定義されている場合、この関数で使用される16ビットエンコーディングはUTF-16である。そうでない場合、実装定義となる。 このマクロは常に定義されており、エンコーディングは常にUTF-16である。 (C23以降) いずれの場合でも、この関数で使用されるマルチバイト文字エンコーディングは、現在有効なCロケールによって指定される。

目次

パラメータ

s - マルチバイト文字が格納されるナロウ文字配列へのポインタ
c16 - 変換対象の16ビットワイド文字
ps - マルチバイト文字列の解釈時に使用される変換状態オブジェクトへのポインタ

戻り値

成功時は、 s が指す先頭要素を持つ文字配列に書き込まれたバイト数(シフトシーケンスを含む)を返します。この値は 0 の場合があります(例:マルチ char16_t 単位シーケンスにおける先頭 char16_t 単位の処理時、UTF-16のサロゲートペアにおける先行サロゲートの処理時に発生)。

失敗時( c16 が有効な16ビットコードユニットでない場合)、 - 1 を返し、 EILSEQ errno に格納し、 * ps を未規定の状態のままにする。

注記

C11で公開された時点では、 mbrtoc16 が可変幅マルチバイト(UTF-8など)から可変幅16ビット(UTF-16など)エンコーディングへの変換を行うのとは異なり、この関数は単一単位の16ビットエンコーディングのみ変換可能です。つまり、この関数の本来の目的であったUTF-16からUTF-8への変換はできません。これはC11以降の欠陥報告書 DR488 によって修正されました。

注: この例は欠陥報告 DR488 の修正が適用されていることを前提としています。
MSVCでは、UTF_8が正しく動作するために /utf-8 コンパイラフラグが必要な場合があります。

#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <uchar.h>
int main(void)
{
    setlocale(LC_ALL, "en_US.utf8");
    const char16_t in[] = u"zß水🍌"; // or "z\u00df\u6c34\U0001F34C"
    const size_t in_sz = sizeof in / sizeof *in;
    printf("Processing %zu UTF-16 code units: [", in_sz);
    for (size_t n = 0; n < in_sz; ++n)
        printf("%s%04X", n ? " " : "", in[n]);
    puts("]");
    char* out = malloc(MB_CUR_MAX * in_sz);
    char* p = out;
    mbstate_t state = {0};
    for (size_t n = 0; n < in_sz; ++n)
    {
        size_t rc = c16rtomb(p, in[n], &state);
        if (rc == (size_t)-1)
            break;
        p += rc;
    }
    size_t out_sz = p - out;
    printf("into %zu UTF-8 code units: [", out_sz);
    for (size_t x = 0; x < out_sz; ++x)
        printf("%s%02X", x ? " " : "", +(unsigned char)out[x]);
    puts("]");
    free(out);
}

出力:

Processing 6 UTF-16 code units: [007A 00DF 6C34 D83C DF4C 0000]
into 13 UTF-8 code units: [7A C3 9F E6 B0 B4 ED A0 BC ED BD 8C 00]

参考文献

  • C23規格 (ISO/IEC 9899:2024):
  • 7.28.1.2 c16rtomb関数 (p: 未定)
  • C17規格 (ISO/IEC 9899:2018):
  • 7.28.1.2 c16rtomb関数 (p: TBD)
  • C11規格 (ISO/IEC 9899:2011):
  • 7.28.1.2 c16rtomb関数 (p: 399-400)

関連項目

ナローマルチバイト文字をUTF-16エンコーディングに変換する
(関数)
C++ documentation for c16rtomb