如何让wstring_convert::to_bytes抛出range_error异常?
How can I get wstring_convert::to_bytes to throw a range_error exception?
我使用std::wstring_convert
将wstring转换为多字节字符串,如下所示:
// 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...
,我希望传递一个将抛出std::range_error
异常的wstring。
然而,我还没有能够表述这样一个将失败这样的转换的wstring。wstring将使用UTF16,我一直在阅读有关高低代理的内容。例如,后跟"b"的UTF16字符D800应该是无效的。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从这个链接。我使用的是Visual Studio 2015.
Microsoft的std::codecvt_utf8
实现似乎成功地将任何UTF-16代码单元转换为utf -8,包括代理对。这是一个bug,因为代理不可编码。libc++ (LLVM)和libstdc++ (GCC)都将正确抛出std::range_error
,并且无法转换未配对的代理。
查看他们的代码,似乎它抛出的唯一方式是如果一个字符大于该facet的Maxcode
模板参数。例如:
std::wstring_convert<std::codecvt_utf8<wchar_t, 0x1>>
正如所指出的—— (已接受的答案)微软的codecvt_utf8
实现似乎存在bug。
我知道我正在处理的字符串总是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);
如果没有单元测试,我永远不会发现这个bug !
相关文章:
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 从构造函数抛出异常时如何克服内存泄漏
- GCC对可能有效的代码抛出init list生存期警告
- 如何在文件和行号中抛出错误
- 我收到以下错误:抛出'std::bad_alloc'实例后终止调用
- cmath抛出错误C2062、C2059、C2143和C2447.cmath包含在矢量文件中
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- Vulkan验证层不断在VkQueuePresentKHR()上抛出图像布局错误
- 如何通过参数抛出错误消息
- 函数如何通知用户它基于函数原型抛出异常?
- 为什么 boost::interprocess::managed_shared_memory 在施工时会抛出 boost
- 将错误返回给调用方而不是立即在 C++ 中抛出错误是否是一种好的做法
- 有没有办法让编译器在我放置字符串而不是 nlohmann::json 对象时抛出错误?
- 编译器错误:destuctor 的更宽松的抛出说明符
- 为什么程序在 c++ 中迭代 emtpy 向量时会抛出运行时错误
- CppSQLite 抛出"LNK2019: unresolved external symbol"错误
- 我应该声明所有不抛出 noexexcept 的成员/函数吗?
- 为什么我的向量::擦除调用会抛出"vector subscript out of range"?
- C++ 向量加减抛出"expression: vector subscript out of range."错误