std::codecvt

来自cppreference.com
< cpp‎ | locale
定义于头文件 <locale>
template<

    class InternT,
    class ExternT,
    class State

> class codecvt;

类模板 std::codecvt 封装字符串的转换,包括宽和多字节,从一种编码到另一种。通过 std::basic_fstream<CharT> 进行的所有 I/O 操作都使用流中感染的 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> 在系统原生宽和单字节窄字符集间转换

另外, C++ 程序中构造每个的 locale 对象实装上述特化其自身的(本地环境特定)版本。

成员类型

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

成员函数

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

成员对象

成员名 类型
id [静态] std::locale::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, mbstate_t> 实现 UTF-8 转换的本地环境读取 UTF-8 环境,并用 std::codecvt 的标准特化转换 UTF-8 字符串为 UTF-16

#include <iostream>
#include <fstream>
#include <string>
#include <locale>
#include <iomanip>
#include <codecvt>
 
// 工具包装器,用于为 wstring/wbuffer 适配绑定到 locale 的平面
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, mbstate_t>
    // 此 locale 的 codecvt 从 UTF-8 转换到 UCS4 (在如 Linux 的系统上)
    fin.imbue(std::locale("en_US.UTF-8"));
    std::cout << "The UTF-8 file contains the following UCS4 code points: \n";
    for (wchar_t c; fin >> c; )
        std::cout << "U+" << std::hex << std::setw(4) << std::setfill('0') << c << '\n';
 
    // 使用标准(本地环境无关) 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 << "The UTF-8 file contains the following UTF-16 code points: \n";
    for (char16_t c : str16)
        std::cout << "U+" << std::hex << std::setw(4) << std::setfill('0') << c << '\n';
}

输出:

The UTF-8 file contains the following UCS4 code points:
U+007a
U+00df
U+6c34
U+1f34c
The UTF-8 file contains the following UTF-16 code points:
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>
N/A
UCS2 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)

定义字符转换错误
(类模板)
为具名本地环境构造 codecvt 平面
(类模板)
(C++11)(C++17 中弃用)
在 UTF-8 与 UCS2/UCS4 间转换
(类模板)
(C++11)(C++17 中弃用)
在 UTF-16 与 UCS2/UCS4 间转换
(类模板)
(C++11)(C++17 中弃用)
在 UTF-8 与 UTF-16 间转换
(类模板)