Xi Xu's More Things

std::codecvt

来自cppreference.com
< cpp‎ | locale
 
 
本地化库
本地环境与平面
本地环境
平面类别基类
ctype(字符类别)平面
codecvt

numeric(数值)平面
collate(对照比较)平面
time(时间)平面
monetary(货币)平面
messages(消息)平面
字符分类与转换
字符分类
转换
编码转换平面
(C++11)
(C++11)    
C 本地环境
 
 
在标头 <locale> 定义
template<

    class InternT,
    class ExternT,
    class StateT

> class codecvt;

类模板 std::codecvt 封装字符串的转换,包括宽和多字节,从一种编码到另一种。通过 std::basic_fstream<CharT> 进行的所有输入/输出操作都使用流中浸染的 std::codecvt<CharT, char, std::mbstate_t> 本地环境平面。

cpp/locale/codecvt basecpp/locale/locale/facetstd-codecvt-inheritance.svg

继承图

特化

标准库保证提供以下特化(所有本地环境对象都需要实现这些特化):

在标头 <locale> 定义
std::codecvt<char, char, std::mbstate_t> 恒等转换
std::codecvt<char16_t, char, std::mbstate_t> 在 UTF-16 和 UTF-8 间转换 (C++11 起)(C++20 中弃用)
std::codecvt<char16_t, char8_t, std::mbstate_t> 在 UTF-16 和 UTF-8 间转换 (C++20 起)
std::codecvt<char32_t, char, std::mbstate_t> 在 UTF-32 和 UTF-8 间转换 (C++11 起)(C++20 中弃用)
std::codecvt<char32_t, char8_t, std::mbstate_t> 在 UTF-32 和 UTF-8 间转换 (C++20 起)
std::codecvt<wchar_t, char, std::mbstate_t> 在系统原生宽和单字节窄字符集间转换

成员类型

成员类型 定义
intern_type InternT
extern_type ExternT
state_type StateT

成员函数

构造新的 codecvt 平面
(公开成员函数)
销毁 codecvt 平面
(受保护成员函数)
调用 do_out
(公开成员函数)
调用 do_in
(公开成员函数)
调用 do_unshift
(公开成员函数)
调用 do_encoding
(公开成员函数)
调用 do_always_noconv
(公开成员函数)
调用 do_length
(公开成员函数)
调用 do_max_length
(公开成员函数)

成员对象

static std::locale::id id
本地环境的 id
(公开成员对象)

受保护成员函数

[虚]
将字符串从 InternT 转换到 ExternT,例如在写入文件时
(虚受保护成员函数)
[虚]
将字符串从 ExternT 转换到 InternT,例如在从文件读取时
(虚受保护成员函数)
为不完整转换生成 ExternT 字符的终止字符序列
(虚受保护成员函数)
返回产生一个 InternT 字符所需的 ExternT 字符数,如果它是常数
(虚受保护成员函数)
测试平面编码是否对所有合法值都是恒等转换
(虚受保护成员函数)
[虚]
计算转换成给定的 InternT 缓冲区会消耗的 ExternT 字符串长度
(虚受保护成员函数)
返回能转换成单个 InternT 字符的最大 ExternT 字符数
(虚受保护成员函数)

继承自 std::codecvt_base

成员类型 定义
enum result { ok, partial, error, noconv }; 无作用域枚举类型
枚举常量 定义
ok 完成转换而无错误
partial 未转换所有源字符
error 遇到非法字符
noconv 不要求转换,输入与输出类型相同

示例

下例示例用在 codecvt<wchar_t, char, std::mbstate_t> 实现 UTF-8 转换的本地环境读取 UTF-8 环境,并用 std::codecvt 的标准特化转换 UTF-8 字符串到 UTF-16。

#include <iostream>
#include <fstream>
#include <string>
#include <locale>
#include <iomanip>
#include <codecvt>
#include <cstdint>
 
// 工具包装器,用于为 wstring/wbuffer 适配绑定到本地环境的平面
template<class Facet>
struct deletable_facet : Facet
{
    template<class... Args>
    deletable_facet(Args&&... args) : Facet(std::forward<Args>(args)...) {}
    ~deletable_facet() {}
};
 
int main()
{
    // UTF-8 窄多字节编码
    std::string data = reinterpret_cast<const char*>(+u8"z\u00df\u6c34\U0001f34c");
                       // 或 reinterpret_cast<const char*>(+u8"zß水🍌")
                       // 或 "\x7a\xc3\x9f\xe6\xb0\xb4\xf0\x9f\x8d\x8c"
 
    std::ofstream("text.txt") << data;
 
    // 使用系统提供的本地环境的 codecvt 平面
    std::wifstream fin("text.txt");
    // 从 wifstream 的读取将使用 codecvt<wchar_t, char, std::mbstate_t>
    // 此本地环境的 codecvt 从 UTF-8 转换到 UCS4(在如 Linux 的系统上)
    fin.imbue(std::locale("en_US.UTF-8"));
    std::cout << "此 UTF-8 文件包含以下 UCS4 编码单元:\n";
    for (wchar_t c; fin >> c;)
        std::cout << "U+" << std::hex << std::setw(4) << std::setfill('0')
                  << static_cast<uint32_t>(c) << ' ';
 
    // 使用标准(本地环境无关)codecvt 平面
    std::wstring_convert<
        deletable_facet<std::codecvt<char16_t, char, std::mbstate_t>>, char16_t> conv16;
    std::u16string str16 = conv16.from_bytes(data);
 
    std::cout << "\n\n此 UTF-8 文件包含以下 UTF-16 编码单元:\n";
    for (char16_t c : str16)
        std::cout << "U+" << std::hex << std::setw(4) << std::setfill('0')
                  << static_cast<uint16_t>(c) << ' ';
}

输出:

此 UTF-8 文件包含以下 UCS4 编码单元:
U+007a U+00df U+6c34 U+1f34c
此 UTF-8 文件包含以下 UTF-16 编码单元:
U+007a U+00df U+6c34 U+d83c U+df4c

参阅

字符转换 本地环境定义多字节
(UTF-8, GB18030)
UTF-8
UTF-16
UTF-16 mbrtoc16 / c16rtomb(有 C11 的 DR488) codecvt<char16_t, char, mbstate_t>
codecvt_utf8_utf16<char16_t>
codecvt_utf8_utf16<char32_t>
codecvt_utf8_utf16<wchar_t>
不适用
UCS-2 c16rtomb(无 C11 的 DR488) codecvt_utf8<char16_t>

codecvt_utf8<wchar_t>(Windows)

codecvt_utf16<char16_t>

codecvt_utf16<wchar_t>(Windows)

UTF-32

mbrtoc32 / c32rtomb

codecvt<char32_t, char, mbstate_t>
codecvt_utf8<char32_t>
codecvt_utf8<wchar_t>(非 Windows)

codecvt_utf16<char32_t>
codecvt_utf16<wchar_t>(非 Windows)

系统宽
UTF-32(非 Windows)
UCS2(Windows)

mbsrtowcs / wcsrtombs
use_facet<codecvt
<wchar_t, char, mbstate_t>>(locale)

定义字符转换错误
(类)
表示系统提供的具名本地环境的 std::codecvt
(类模板)
(C++11)(C++17 中弃用)
在 UTF-8 与 UCS-2/UCS-4 间转换
(类模板)
(C++11)(C++17 中弃用)
在 UTF-16 与 UCS-2/UCS-4 间转换
(类模板)
(C++11)(C++17 中弃用)
在 UTF-8 与 UTF-16 间转换
(类模板)