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 не является нулевым указателем и c16 является последним 16-битным кодовым юнитом в корректной переменной длине кодировки кодовой точки, функция определяет количество байтов, необходимое для хранения многобайтового представления этого символа (включая сдвиговые последовательности и учитывая текущее состояние многобайтового преобразования * ps ), и сохраняет многобайтовое представление символа в массиве символов, на первый элемент которого указывает s , обновляя * ps при необходимости. Функция может записать не более MB_CUR_MAX байтов.

Если s является нулевым указателем, вызов эквивалентен c16rtomb ( buf, u ' \0 ' , ps ) для некоторого внутреннего буфера buf .

Если 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 (стр.: TBD)
  • Стандарт C17 (ISO/IEC 9899:2018):
  • 7.28.1.2 Функция c16rtomb (стр.: TBD)
  • Стандарт C11 (ISO/IEC 9899:2011):
  • 7.28.1.2 Функция c16rtomb (стр: 399-400)

Смотрите также

преобразует узкий многобайтовый символ в кодировку UTF-16
(функция)
C++ documentation для c16rtomb