Namespaces
Variants

std:: codecvt

From cppreference.net
定义于头文件 <locale>
template <

class InternT,
class ExternT,
class StateT

> class codecvt ;

类模板 std::codecvt 封装了字符串(包括宽字符和多字节字符)在不同编码间的转换。所有通过 std:: basic_fstream < CharT > 执行的文件 I/O 操作均使用流所植入区域设置的 std :: codecvt < CharT, char , std:: mbstate_t > facet。

cpp/locale/codecvt base cpp/locale/locale/facet std-codecvt-inheritance.svg

继承关系图

目录

特化

标准库保证提供以下特化(它们 是任何locale对象必须实现的 ):

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

嵌套类型

类型 定义
intern_type InternT
extern_type ExternT
state_type StateT

数据成员

成员 描述
std::locale::id id [静态] facet 的标识符

成员函数

构造新的 codecvt facet
(公开成员函数)
调用 do_out
(公开成员函数)
调用 do_in
(公开成员函数)
调用 do_unshift
(公开成员函数)
调用 do_encoding
(公开成员函数)
调用 do_always_noconv
(公开成员函数)
调用 do_length
(公开成员函数)
调用 do_max_length
(公开成员函数)

受保护成员函数

析构 codecvt facet
(受保护成员函数)
[virtual]
将字符串从 InternT 转换为 ExternT ,例如写入文件时
(虚受保护成员函数)
[virtual]
将字符串从 ExternT 转换为 InternT ,例如从文件读取时
(虚受保护成员函数)
[virtual]
为不完整转换生成 ExternT 字符的终止字符序列
(虚受保护成员函数)
[virtual]
返回生成一个 InternT 字符所需的 ExternT 字符数量(若为常量)
(虚受保护成员函数)
测试该 facet 是否对所有有效参数值执行恒等转换
(虚受保护成员函数)
[virtual]
计算转换为给定 InternT 缓冲区时将消耗的 ExternT 字符串长度
(虚受保护成员函数)
[virtual]
返回可转换为单个 InternT 字符的最大 ExternT 字符数
(虚受保护成员函数)

继承自 std:: codecvt_base

嵌套类型 定义
enum result { ok, partial, error, noconv } ; 非限定作用域枚举类型
枚举常量 定义
ok 转换成功完成且无错误
partial 未转换全部源字符
error 遇到无效字符
noconv 无需转换,输入与输出类型相同

示例

以下示例使用实现了 UTF-8 转换的区域设置(通过 codecvt < wchar_t , char , std:: mbstate_t > )读取 UTF-8 文件,并使用 std::codecvt 的标准特化之一将 UTF-8 字符串转换为 UTF-16。

#include <codecvt>
#include <cstdint>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <locale>
#include <string>
// utility wrapper to adapt locale-bound facets for wstring/wbuffer convert
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 narrow multibyte encoding
    std::string data = reinterpret_cast<const char*>(+u8"z\u00df\u6c34\U0001f34c");
                       // or reinterpret_cast<const char*>(+u8"zß水🍌")
                       // or "\x7a\xc3\x9f\xe6\xb0\xb4\xf0\x9f\x8d\x8c"
    std::ofstream("text.txt") << data;
    // using system-supplied locale's codecvt facet
    std::wifstream fin("text.txt");
    // reading from wifstream will use codecvt<wchar_t, char, std::mbstate_t>
    // this locale's codecvt converts UTF-8 to UCS4 (on systems such as Linux)
    fin.imbue(std::locale("en_US.UTF-8"));
    std::cout << "The UTF-8 file contains the following UCS4 code units:\n" << std::hex;
    for (wchar_t c; fin >> c;)
        std::cout << "U+" << std::setw(4) << std::setfill('0')
                  << static_cast<uint32_t>(c) << ' ';
    // using standard (locale-independent) codecvt facet
    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\nThe UTF-8 file contains the following UTF-16 code units:\n"
              << std::hex;
    for (char16_t c : str16)
        std::cout << "U+" << std::setw(4) << std::setfill('0')
                  << static_cast<uint16_t>(c) << ' ';
    std::cout << '\n';
}

输出:

The UTF-8 file contains the following UCS4 code units:
U+007a U+00df U+6c34 U+1f34c 
The UTF-8 file contains the following UTF-16 code units:
U+007a U+00df U+6c34 U+d83c U+df4c

缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的C++标准。

缺陷报告 应用于 发布时行为 正确行为
LWG 3767 C++20 std :: codecvt < char16_t , char8_t, std:: mbstate_t >
std :: codecvt < char32_t , char8_t, std:: mbstate_t > 是区域设置无关的
将其弃用

参见

字符
转换
区域设置定义的多字节
(UTF-8, GB18030)
UTF-8
UTF-16
UTF-16 mbrtoc16 / c16rtomb (with C11's 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 (without C11's DR488) codecvt_utf8 < char16_t > codecvt_utf16 < char16_t >
UTF-32

mbrtoc32 / c32rtomb

codecvt < char32_t , char ,mbstate_t >
codecvt_utf8 < char32_t >

codecvt_utf16 < char32_t >

系统 wchar_t :

UTF-32 (非Windows)
UCS-2 (Windows)

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

codecvt_utf8 < wchar_t > codecvt_utf16 < wchar_t >
定义字符转换错误
(类)
表示系统提供的命名区域设置的 std::codecvt
(类模板)
(C++11) (C++17 中弃用) (C++26 中移除)
在 UTF-8 和 UCS-2/UCS-4 之间转换
(类模板)
(C++11) (C++17 中弃用) (C++26 中移除)
在 UTF-16 和 UCS-2/UCS-4 之间转换
(类模板)
(C++11) (C++17 中弃用) (C++26 中移除)
在 UTF-8 和 UTF-16 之间转换
(类模板)