命名空间
变体
操作

std::codecvt

来自 cppreference.com
< cpp‎ | locale
 
 
 
 
定义在头文件 <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> 构面。

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>
(自 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

[编辑] 成员函数

构造一个新的 codecvt 构面
(公共成员函数)
调用 do_out
(公共成员函数) [编辑]
调用 do_in
(公共成员函数) [编辑]
调用 do_unshift
(公共成员函数) [编辑]
调用 do_encoding
(公共成员函数) [编辑]
调用 do_always_noconv
(公共成员函数) [编辑]
调用 do_length
(公共成员函数) [编辑]
调用 do_max_length
(公共成员函数) [编辑]

[编辑] 成员对象

static std::locale::id id
id 区域设置
(公共成员对象)

[编辑] 受保护的成员函数

析构一个 codecvt 构面
(受保护的成员函数)
[虚函数]
将字符串从 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 文件,并将 UTF-8 字符串转换为 UTF-16,使用 std::codecvt 的一个标准特化。

#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++ 标准。

DR 应用于 已发布的行为 正确行为
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 (使用 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
UCS-2 c16rtomb (未使用 C11 的 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 之间转换
(类模板) [编辑]