如何获取wstring_convert :: to_bytes引发range_error异常?

问题描述:

我使用std::wstring_convert到的wstring转换成多字节字符串如下:如何获取wstring_convert :: to_bytes引发range_error异常?

// convert from wide char to multibyte char 
    try 
    { 
     return std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(wideMessage); 
    } 

    // thrown by std::wstring_convert.to_bytes() for bad conversions 
    catch (std::range_error& exception) 
    { 
     // do something... 
    } 

为了单元测试我有评论为do something...块我想传递一个的wstring,将抛出一个异常std::range_error

但是,我还没有能够制定这样一个wstring,将失败这样的转换。 wstring将使用UTF16,我一直在阅读关于高和低代理。例如,D800后跟“b”的UTF16字符应该无效。 std::wstring(L"\xd800b");可能无法在相同的理由上进行编译。如果我创建一个wstring的,如下面也不会扔在转换异常:

std::wstring wideMessage(L" b"); 
wideMessage[0] = L'\xd800'; 

// doesn't throw 
std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(wideMessage); 

是否有合适的wstring我可以使用在转换过程中抛出一个异常?

我试过5.1,5.2和5.3,从this link。我正在使用Visual Studio 2015.

+1

你正在使用哪种编译器和STL?这工作(或抛出)完全符合我使用clang/libC++ 3.6的预期。 –

+0

Visual Studio 2015 – camelCase

微软实施std::codecvt_utf8似乎已成功将任何UTF-16代码单元转换为UTF-8(包括代理对)。这是一个错误,因为代理不可编码。 libC++(LLVM)和libstdC++(GCC)都会正确地抛出std::range_error,并且无法转换未配对的代理。

看着他们的代码,看起来它唯一的出路是如果一个字符大于方面的Maxcode模板参数。例如:

std::wstring_convert<std::codecvt_utf8<wchar_t, 0x1>> 
+0

也许我应该使用'codecvt_utf8_utf16',因为我知道源代码是UTF16(并且'codecvt_utf8_utf16'确实会抛出我之前测试中传入的示例)。 – camelCase

正如指出的一二三(接受的答案)微软的落实codecvt_utf8似乎被窃听。

我知道我处理的字符串总是UTF16,我想转换为UTF8。我最终改变执行如下命令:

// convert from wide char to multibyte char 
    try 
    { 
     return std::wstring_convert<std::codecvt_utf8_utf16 <wchar_t>>().to_bytes(wideMessage); 
    } 

    // thrown by std::wstring_convert.to_bytes() for bad conversions 
    catch (const std::range_error & exception) 
    { 
     // do something... 
    } 

下可以正确地抛出:

std::wstring wideMessage(L" b"); 
wideMessage[0] = L'\xd800'; 

// throw std::range_error 
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>().to_bytes(wideMessage); 

我从来没有发现这个错误没有单元测试!

+1

您是否在[Microsoft Connect](https://connect.microsoft.com/VisualStudio)上报告了此错误? –

+0

@jamesmcnellis nope,没有阅读标准说的内容。可能是特定于实现的。 – camelCase