gpt4 book ai didi

c++ - std::codecvt_utf8 方面的问题

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:37:03 24 4
gpt4 key购买 nike

这是使用 std::codecvt_utf8<> 的代码片段要从 wchar_t 转换的方面到 UTF-8。使用 Visual Studio 2012,我的期望没有达到(请参阅代码末尾的条件)。我的期望错了吗?为什么?或者这是一个 Visual Studio 2012 库问题?

#include <locale>
#include <codecvt>
#include <cstdlib>

int main ()
{
std::mbstate_t state = std::mbstate_t ();
std::locale loc (std::locale (), new std::codecvt_utf8<wchar_t>);
typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type;
codecvt_type const & cvt = std::use_facet<codecvt_type> (loc);

wchar_t ch = L'\u5FC3';
wchar_t const * from_first = &ch;
wchar_t const * from_mid = &ch;
wchar_t const * from_end = from_first + 1;

char out_buf[1];
char * out_first = out_buf;
char * out_mid = out_buf;
char * out_end = out_buf + 1;

std::codecvt_base::result cvt_res
= cvt.out (state, from_first, from_end, from_mid,
out_first, out_end, out_mid);

// This is what I expect:
if (cvt_res == std::codecvt_base::partial
&& out_mid == out_end
&& state != 0)
;
else
abort ();
}

这里的期望是 out()函数一次输出 UTF-8 转换的一个字节,但 if 的中间对于 Visual Studio 2012,上述条件为假。

更新

失败的是 out_mid == out_endstate != 0状况。基本上,我希望至少生成一个字节和必要的状态,以便生成 UTF-8 序列的下一个字节,并将其存储在 state 中。变量。

最佳答案

codecvt::do_outpartial 返回码的标准描述就是这样说的:

在表 83 中:

partial not all source characters converted

在 22.4.1.4.2[locale.codecvt.virtuals]/5 中:

Returns: An enumeration value, as summarized in Table 83. A return value of partial, if (from_next==from_end), indicates that either the destination sequence has not absorbed all the available destination elements, or that additional source elements are needed before another destination element can be produced.

在您的情况下,并非所有(零个)源字符都被转换,从技术上讲,这与输出序列的内容无关(未输入句子中的“if”子句),但一般来说,“目标序列没有吸收所有可用的目标元素”这里讨论有效的多字节字符。它们是由 codecvt_utf8 生成的多字节字符序列的元素

最好有一个更明确的标准措辞,但这里有两个间接证据:

一:旧 C 的宽字节到多字节转换函数 std::wcsrtombs(其特定于语言环境的变体通常由 codecvt::do_out 的现有实现调用> 对于系统提供的语言环境)定义如下:

Conversion stops [...] when the next multibyte character would exceed the limit of len total bytes to be stored into the array pointed to by dst.

其二,查看 codecvt_utf8 的现有实现:您已经探索了 Microsoft 的,这是 libc++ 中的内容:codecvt_utf8::do_out 此处调用 Windows 上的 ucs2_to_utf8 和其他系统上的 ucs4_to_utf8,以及 ucs2_to_utf8 does the following (评论我的):

        else if (wc < 0x0800)
{
// not relevant
}
else // if (wc <= 0xFFFF)
{
if (to_end-to_nxt < 3)
return codecvt_base::partial; // <- look here
*to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
*to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
}

如果输出序列无法容纳因消耗一个输入宽字符而产生的多字节字符,则不会向输出序列写入任何内容。

关于c++ - std::codecvt_utf8 方面的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19357027/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com