为什么wstring_convert会抛出range_error?

时间:2015-05-31 05:34:19

标签: c++ c++11 locale wstring

我正在编写一些需要使用系统区域设置在字节字符串和宽字符串之间进行转换的代码。从文件中读取时,这非常容易。我可以使用std::wifstream,将其与std::locale("")一起使用,然后只使用std::getline

根据cppreference的codecvt页面,wifstream只使用codecvt<wchar_t, char, mbstate_t>,因此我认为我可以通过使用std::stringstd::wstring进行转换那个:

// 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() {}
};

std::locale::global(std::locale(""));
std::wstring_convert<
    deletable_facet<std::codecvt<wchar_t, char, std::mbstate_t>>> wconv;
std::wstring wstr = wconv.from_bytes(data);

但是,当我尝试运行此操作时,我会从range_error中抛出wstring_convert。我做了一些谷歌搜索,显然当wstring_convert无法转换字符串时会发生这种情况。

但是,这些字符串显然可以使用wfstream进行转换,codecvt应使用与我wstring_convert一样的wifstream。那么为什么wstring_convert有效,但string没有?

有没有办法可以使用系统的区域设置在wstringsizeof(char32_t) = 4 sizeof(wchar_t) = 4 The UTF-8 file contains the following UCS4 code points: U+007a U+00df U+6c34 U+1f34c The UTF-8 string contains the following UCS4 code points: U+007a U+00df U+6c34 U+1f34c terminate called after throwing an instance of 'std::range_error' what(): wstring_convert Aborted (core dumped) 之间进行转换?

我的问题的完整示例(codecvt页面改编自here,输出为:

{{1}}

1 个答案:

答案 0 :(得分:2)

您的wifstreamwstring_convert正在使用不同的方面。

wifstream正在使用依赖于区域设置的转换方面;它通过std::locale("")

将其从std::use_facet拉出来,并将其融入其中

wstring_convert被赋予了一个独立于语言环境的独立codecvt方面,而你的实现提供的方面显然不会将UTF-8转换为适合的任何东西;尝试直接在其上调用in以查看它的作用。

获取依赖于语言环境的方面的简单方法是按名称请求它,如 std::codecvt_byname