名前空間
変種
操作

c16rtomb

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

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

sがヌルポインタでなく、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です。(since C23) いずれの場合も、この関数で使用されるマルチバイト文字エンコーディングは、現在アクティブなCロケールによって指定されます。

目次

[編集] パラメータ

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

[編集] 戻り値

成功した場合、sが指す文字配列に書き込まれたバイト数(シフトシーケンスを含む)を返します。この値は 0 になることもあります。例えば、マルチ char16_t ユニットシーケンスの先頭の char16_t ユニットを処理する場合(UTF-16のサロゲートペアの先頭サロゲートを処理する場合に発生します)。

失敗した場合(c16が無効な16ビットコードユニットの場合)、-1を返し、EILSEQerrno に格納し、*ps は未指定の状態にします。

[編集] 注記

C11の公開版では、可変幅マルチバイト(UTF-8など)を可変幅16ビット(UTF-16など)エンコーディングに変換する mbrtoc16 とは異なり、この関数は単一ユニットの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: TBD)
  • 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エンコーディングに変換する
(関数) [編集]
English 日本語 中文(简体) 中文(繁體)