我正在编写一些需要使用系统区域设置在字节字符串和宽字符串之间进行转换的代码。从文件中读取时,这非常容易。我可以使用std::wifstream
,将其与std::locale("")
一起使用,然后只使用std::getline
。
根据cppreference的codecvt页面,wifstream
只使用codecvt<wchar_t, char, mbstate_t>
,因此我认为我可以通过使用std::string
和std::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
没有?
有没有办法可以使用系统的区域设置在wstring
和sizeof(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}}
答案 0 :(得分:2)
您的wifstream
和wstring_convert
正在使用不同的方面。
wifstream
正在使用依赖于区域设置的转换方面;它通过std::locale("")
std::use_facet
拉出来,并将其融入其中
wstring_convert
被赋予了一个独立于语言环境的独立codecvt方面,而你的实现提供的方面显然不会将UTF-8转换为适合的任何东西;尝试直接在其上调用in以查看它的作用。
获取依赖于语言环境的方面的简单方法是按名称请求它,如 std::codecvt_byname