命名空间
变体
操作

std::codecvt<InternT,ExternT,StateT>::out, do_out

来自 cppreference.cn
< cpp‎ | locale‎ | codecvt
 
 
 
 
 
定义于头文件 <locale>
public:

result out( StateT& state,
            const InternT* from,
            const InternT* from_end,
            const InternT*& from_next,
            ExternT* to,
            ExternT* to_end,

            ExternT*& to_next ) const;
(1)
protected:

virtual result do_out( StateT& state,
                       const InternT* from,
                       const InternT* from_end,
                       const InternT*& from_next,
                       ExternT* to,
                       ExternT* to_end,

                       ExternT*& to_next ) const;
(2)
1) 公有成员函数,调用派生程度最高的类(most derived class)的成员函数 do_out
2) 若此 codecvt facet 定义了转换,则将源范围 [fromfrom_end) 中的内部字符翻译为外部字符,将结果放置在从 to 开始的后续位置。最多转换 from_end - from 个内部字符,最多写入 to_end - to 个外部字符。让 from_nextto_next 指向成功转换的最后一个元素之后的位置。

若此 codecvt facet 未定义转换,则不转换任何字符。to_next 设置为等于 tostate 保持不变,并返回 std::codecvt_base::noconv

do_out(state, from, from + 1, from_next, to, to_end, to_next) 必须返回 ok,若

  • codecvt facet 为 basic_filebuf 所用,且
  • do_out(state, from, from_end, from_next, to, to_end, to_next) 将返回 ok,其中 from != from_end

目录

[编辑] 返回值

一个 std::codecvt_base::result 类型的值,指示成功状态,如下所示

ok 转换完成
部分 输出缓冲区中空间不足,或源缓冲区意外结束
error 遇到无法转换的字符
noconv 此 facet 不执行转换,未写入输出

非转换特化 std::codecvt<char, char, std::mbstate_t> 始终返回 std::codecvt_base::noconv

[编辑] 注意

要求 from <= from_end && to <= to_end,并且 state 要么表示初始移位状态,要么通过转换序列中前面的字符获得。

尽管 codecvt 支持 N:M 转换(例如 UTF-16 到 UTF-8,其中可能需要两个内部字符来决定输出哪些外部字符),但 std::basic_filebuf 只能使用定义 1:N 转换的 codecvt facet,即在写入文件时,它必须能够一次处理一个内部字符。

执行 N:M 转换时,此函数可能在消耗所有源字符(from_next == from_end)后返回 std::codecvt_base::partial。这意味着需要另一个内部字符来完成转换(例如,当将 UTF-16 转换为 UTF-8 时,如果源缓冲区中的最后一个字符是高代理项)。

state 的影响是故意未指定的。在标准 facet 中,它用于维护移位状态,如同调用 std::wcsrtombs 时,因此会更新以反映最后成功转换的字符后的移位状态,但用户定义的 facet 可以自由使用它来维护任何其他状态,例如计算遇到的特殊字符的数量。

[编辑] 示例

#include <iostream>
#include <locale>
#include <string>
 
int main()
{
    std::locale::global(std::locale("en_US.utf8"));
    auto& f = std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(std::locale());
    std::wstring internal = L"z\u00df\u6c34\U0001f34c"; // L"zß水🍌"
 
    // note that the following can be done with wstring_convert
    std::mbstate_t mb{}; // initial shift state
    std::string external(internal.size() * f.max_length(), '\0'); 
    const wchar_t* from_next;
    char* to_next;
    f.out(mb, &internal[0], &internal[internal.size()], from_next,
              &external[0], &external[external.size()], to_next);
    // error checking skipped for brevity
    external.resize(to_next - &external[0]);
 
    std::cout << "The string in narrow multibyte encoding: " << external << '\n';
}

输出

The string in narrow multibyte encoding: zß水🍌

[编辑] 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 发布时的行为 正确的行为
LWG 76 C++98 不清楚转换是否要求
支持一次处理一个内部字符
仅在被
basic_filebuf 使用时要求

[编辑] 参阅

[virtual]
从放置区向关联文件写入字符
std::basic_filebuf<CharT,Traits> 的虚保护成员函数) [编辑]
将宽字符串转换为字节字符串
std::wstring_convert<Codecvt,Elem,Wide_alloc,Byte_alloc> 的公有成员函数) [编辑]
将宽字符串转换为窄多字节字符字符串,给定状态
(函数) [编辑]
[virtual]
将字符串从 ExternT 转换为 InternT,例如从文件读取时
(虚保护成员函数) [编辑]