如何获取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.
微软实施std::codecvt_utf8
似乎已成功将任何UTF-16代码单元转换为UTF-8(包括代理对)。这是一个错误,因为代理不可编码。 libC++(LLVM)和libstdC++(GCC)都会正确地抛出std::range_error
,并且无法转换未配对的代理。
看着他们的代码,看起来它唯一的出路是如果一个字符大于方面的Maxcode
模板参数。例如:
std::wstring_convert<std::codecvt_utf8<wchar_t, 0x1>>
也许我应该使用'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);
我从来没有发现这个错误没有单元测试!
您是否在[Microsoft Connect](https://connect.microsoft.com/VisualStudio)上报告了此错误? –
@jamesmcnellis nope,没有阅读标准说的内容。可能是特定于实现的。 – camelCase
你正在使用哪种编译器和STL?这工作(或抛出)完全符合我使用clang/libC++ 3.6的预期。 –
Visual Studio 2015 – camelCase