在基于英语的系统上将UTF-8路径转换为宽字符会引发异常

时间:2018-10-04 13:02:08

标签: c++ utf-8 internationalization

我有一个可扫描文件夹路径并将其呈现给用户的应用程序。长期以来,我一直在使用一个简单的实用程序将UTF-8转换为宽字符串。运行得很好。但是今天它开始引发异常,我需要弄清楚该怎么办。

这是功能。

inline std::wstring convertutf8(const std::string& p) 
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> wconv;
    return wconv.from_bytes(p.c_str());
}

今天,该实用程序首次尝试转换此字符串,但出现异常

  

I:\ Scans \ Nouvelles计数

这是我运行法语版本的其他应用程序并将某些内容保存到应用程序扫描的文件夹时创建的文件夹路径。 (我正在使用以英语-美国为本地语言的系统上运行。)

此路径导致标准C ++库从from_bytes函数内部引发range_error异常(文本为“ bad conversion”),该标准库似乎无法转换带有重音符号的字符...

  

é

我可以看到几种处理这种情况的方法,包括捕获异常(并返回“”)或在这种情况下返回默认错误字符串。 (wstring_convert在构造函数中为此提供了便利)。但是我需要更好地理解这一点。

我愚蠢地希望将wstring_convert与codecvt_utf8结合使用可以让我处理这种情况。到目前为止,我的应用程序似乎可以正确地处理中文路径。所以我很惊讶这给我带来麻烦

当我在调试器(及其周围的代码)中查看问题字符的文本时,会看到以下内容

CHAR   DEC     HEX
----   ---     ----
 'n'   110     0x6e
 'u'   117     0x75
 'm'   109     0x6d
 'é'   -23     0xe9
 'r'   114     0x72
 'i'   105     0x69

那些数字代表“正确的” UTF-8表示吗?我什至不知道。国际化对我来说不是一个合适的选择。

我在这里做错什么了吗?缺少简单的东西吗?这是扫描文件夹并将其呈现给用户以进行导航的应用程序的一部分。我希望能够处理带有此类字符的路径的情况,将其正确转换并继续。

在这种情况下,有人可以给我一些有关我 应该做什么的指导,以便能够在基于英语的系统上处理这样的问题吗?

1 个答案:

答案 0 :(得分:1)

sprintf通过抛出异常来做正确的事情。

std::wstring_convert对于字符0xe9不是有效的UTF-8字节序列。只需要对0-127(基本ASCII)范围内的代码点进行特殊编码。

字符é的有效UTF-8字节序列如下所示(try for yourself):

é
  

在这种情况下,我应该怎么做才能处理   基于英语的系统?

这种情况是输入错误,应这样处理。例如,将错误报告给用户,以便他们修复输入。