Namespaces
Variants

wcrtomb, wcrtomb_s

From cppreference.net
定义于头文件 <wchar.h>
(1)
size_t wcrtomb ( char * s, wchar_t wc, mbstate_t * ps ) ;
(C95起)
size_t wcrtomb ( char * restrict s, wchar_t wc, mbstate_t * restrict ps ) ;
(C99起)
errno_t wcrtomb_s ( size_t * restrict retval, char * restrict s, rsize_t ssz,
wchar_t wc, mbstate_t * restrict ps ) ;
(2) (C11起)

将宽字符转换为其窄多字节表示形式。

1) s 不是空指针,该函数会确定存储宽字符 wc 的多字节字符表示形式所需的字节数(包括任何移位序列,并考虑当前多字节转换状态 * ps ),然后将多字节字符表示形式存储到由 s 指向首元素的字符数组中,并视需要更新 * ps 。此函数最多可写入 MB_CUR_MAX 字节。
s 是空指针,则调用等价于 wcrtomb ( buf, L ' \0 ' , ps ) (对某个内部缓冲区 buf )。
若 wc 是空宽字符 L ' \0 ' ,将存储空字节,并在其前附加恢复初始移位状态所需的任何移位序列,同时转换状态参数 * ps 将被更新以表示初始移位状态。
若定义了环境宏 __STDC_ISO_10646__ ,则类型 wchar_t 的值与Unicode必需字符集的短标识符相同(通常为UTF-32编码);否则由具体实现定义。无论何种情况,此函数使用的多字节字符编码由当前生效的C区域设置指定。
2) (1) 相同,不同之处在于
s 为空指针,该调用等价于 wcrtomb_s ( & retval, buf, sizeof buf, L ' \0 ' , ps ) (使用内部变量 retval buf ,其大小大于 MB_CUR_MAX
结果通过输出参数 retval 返回
以下错误在运行时被检测到,并会调用当前安装的 约束处理函数
  • retval ps 是空指针。
  • ssz 为零或大于 RSIZE_MAX (除非 s 为空)
  • ssz 小于将被写入的字节数(除非 s 为空)
  • s 是空指针但 ssz 不为零
与所有边界检查函数一样,仅当实现定义了 __STDC_LIB_EXT1__ 且用户在包含 <wchar.h> 前将 __STDC_WANT_LIB_EXT1__ 定义为整型常量 1 时,才保证 wcrtomb_s 可用。

目录

参数

s - 指向用于存储多字节字符的窄字符数组的指针
wc - 待转换的宽字符
ps - 解释多字节字符串时使用的转换状态对象的指针
ssz - 最大写入字节数(缓冲区 s 的大小)
retval - 指向输出参数的指针,用于存储结果(多字节字符串中的字节数,包括任何移位序列)

返回值

1) 成功时,返回写入到以 s 所指向的首元素的字符数组的字节数(包含任何移位序列)。
当失败时(如果 wc 不是有效的宽字符),返回 ( size_t ) - 1 ,将 EILSEQ 存入 errno ,并使 * ps 保持未指定状态。
2) 成功时返回零,失败时返回非零值。失败时, s [ 0 ] 将被设为 ' \0 ' (除非 s 为空指针,或 ssz 为零,或大于 RSIZE_MAX ),同时 * retval 将被设为 ( size_t ) - 1 (除非 retval 为空指针)

示例

#include <stdio.h>
#include <locale.h>
#include <string.h>
#include <wchar.h>
#include <stdlib.h>
int main(void)
{
    setlocale(LC_ALL, "en_US.utf8");
    mbstate_t state;
    memset(&state, 0, sizeof state);
    wchar_t in[] = L"zß水🍌"; // 或 "z\u00df\u6c34\U0001F34C"
    size_t in_sz = sizeof in / sizeof *in;
    printf("正在处理 %zu 个宽字符单元:[ ", in_sz);
    for(size_t n = 0; n < in_sz; ++n) printf("%#x ", (unsigned int)in[n]);
    puts("]");
    char out[MB_CUR_MAX * in_sz];
    char *p = out;
    for(size_t n = 0; n < in_sz; ++n) {
        int rc = wcrtomb(p, in[n], &state); 
        if(rc == -1) break;
        p += rc;
    }
    size_t out_sz = p - out;
    printf("转换为 %zu 个UTF-8编码单元:[ ", out_sz);
    for(size_t x = 0; x < out_sz; ++x) printf("%#x ", +(unsigned char)out[x]);
    puts("]");
}

输出:

Processing 5 wchar_t units: [ 0x7a 0xdf 0x6c34 0x1f34c 0 ]
into 11 UTF-8 code units: [ 0x7a 0xc3 0x9f 0xe6 0xb0 0xb4 0xf0 0x9f 0x8d 0x8c 0 ]

参考文献

  • C11 标准 (ISO/IEC 9899:2011):
  • 7.29.6.3.3 wcrtomb 函数 (p: 444)
  • K.3.9.3.1.1 wcrtomb_s 函数 (p: 647-648)
  • C99 标准 (ISO/IEC 9899:1999):
  • 7.24.6.3.3 wcrtomb 函数 (p: 390)

参见

将宽字符转换为其多字节表示形式
(函数)
(C95)
在给定状态下将下一个多字节字符转换为宽字符
(函数)
C++ 文档 for wcrtomb