如何检查转换为wchar_t“失败”

时间:2011-08-12 08:47:53

标签: c++ unicode

我有一个代码可以做这样的事情:

char16_t msg[256]={0};
//...
wstring wstr;
for (int i =0;i<len;++i)
    {
        if((unsigned short)msg[i]!=167)
                wstr.push_back((wchar_t) msg[i]);
            else
                wstr.append(L"_<?>_");
    }

你可以看到它使用一些相当难看的硬编码(我不确定它是否有效,但它适用于我的数据)来确定wchar_t是否“失败”(即替换字符的值)  来自wiki:

  

替换字符 (通常是带有白色的黑色钻石   问号)是在codepoint的Unicode标准中找到的符号   特价表中的U + FFFD。它用于表示a时的问题   系统无法将数据流解码为正确的符号。它   当字体不包含字符时最常见,但是   当数据无效且与任何字符都不匹配时也会看到:

所以我有两个问题: 1.有没有正确的方法来做到这一点? 2.是否有其他字符如替换字符表示转换失败?

编辑:我在linux上使用gcc所以wchar_t是32位,我之所以需要这个强制转换是因为奇怪的wstrings杀了我的glog库。 :)还有wcout死了。 :(:)

4 个答案:

答案 0 :(得分:3)

不能那样工作。 wchar_tchar16_t都是C ++中的整数类型。从一个到另一个的转换遵循通常的整数转换规则,它不会尝试以任何方式在字符集之间进行转换,或者验证任何内容都是真正的unicode代码点。

任何替换字符都必须来自比简单演员更复杂的代码(或者当然可以来自原始输入)。

提供:

  1. msg中的输入是BMP中的一系列代码点
  2. 您实现中的
  3. wchar_t至少为16位,您的实现使用的宽字符集是Unicode(或16位版本的Unicode,无论是仅BMP还是UTF-16)。 / LI>

    然后你的代码应该可以正常工作。但是,它不会验证输入,只需复制值。

答案 1 :(得分:3)

如果要在C ++中实际处理Unicode字符串(而不仅仅是16位值的序列),则应使用International Components for Unicode(ICU)库。引用FAQ

  

为何选择ICU4C?

     

C和C ++语言以及许多操作系统环境不能完全支持Unicode和符合标准的文本处理服务。尽管某些平台确实提供了良好的Unicode文本处理服务,但便携式应用程序代码无法使用它们。 ICU4C图书馆填补了这一空白。 ICU4C为应用程序提供了一个开放,灵活,可移植的基础,用于满足其软件全球化要求。 ICU4C密切跟踪行业标准,包括Unicode和CLDR(通用区域数据存储库)。

作为副作用,如果转换失败,您会收到正确的错误报告......

答案 2 :(得分:2)

如果您不介意特定于平台的代码,则Windows会使用MultiByteToWideChar API。

*编辑:我看到你在Linux上;我会在这里留下我的答案,以防Windows用户可以从中受益。

答案 3 :(得分:1)

施法者不会失败也不会产生任何替换字符。代码中的167值并不表示失败的强制转换,这意味着只有代码的作者知道的其他内容。

仅供参考,Unicode代码点167(0x00A7)是section sign:§。也许这会对代码应该做的事情产生一些影响。

虽然我不知道它是什么,但考虑用以下方法重写它:

wchar_t msg[256];
...
wstring wstr(msg, wcslen(msg));

char16_t msg[256];
...
u16string u16str(msg, wcslen(msg));

然后根据需要对167值执行某些操作。