wstring_convert为什么会引发range_error?

问题描述:

我正在写一些代码,需要使用系统区域设置在字节字符串和宽字符串之间进行转换。从文件中读取时,这非常容易。我可以使用std::wifstream,将其与std::locale("")一起插入,然后使用std::getlinewstring_convert为什么会引发range_error?

根据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); 

然而,当我尝试运行此,我从wstring_convert得到range_error。我做了一些Google搜索,显然这是wstring_convert无法转换字符串时发生的情况。

但是,这些字符串显然完全可以使用wfstream进行转换,这应与我使用的wstring_convert使用相同的codecvt。那么为什么wifstream工作,但wstring_convert不?

有没有一种方法可以在string s和wstring之间使用系统的区域设置进行转换?

我的问题,改编自codecvt页面的完整例子,是here,并输出结果是:

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) 

wifstreamwstring_convert使用不同的方面。

wifstream正在使用依赖于语言环境的转换刻面;它拉出来的std::locale(""),与它一脉相承,通过std::use_facet

wstring_convert被赋予了语言环境无关的,独立的codecvt面,并通过您的实现提供了一个显然不转换UTF-8成什么配件;请尝试直接调用in以查看它的功能。

一个简单的方法来获得一个语言环境相关的方面是通过名字来要求它,在 std::codecvt_byname

+0

谢谢!通过替换wstring_convert定义修复: 'typedef deletable_facet > local_facet_t; std :: wstring_convert wconv(new local_facet_t(“”));' – Anachrome