如何知道wstring是否可以安全(没有数据丢失)转换为字符串?

时间:2014-10-26 07:21:00

标签: string c++11 type-conversion wstring

所以我已经知道如何将wstring转换为stringHow to convert wstring into string?)。

但是,我想知道转换是否安全,这意味着wstring变量包含{{1}不支持的任何字符} type。

1 个答案:

答案 0 :(得分:1)

如果使用正确的编码,

字符串可以保存任何数据。它们只是字节序列。但是您需要检查特定的编码/转换例程。

应该只是一个往返的问题。许多事情的优雅解决方案。

警告,伪代码,除非你这样做,否则没有文字convert_to_wstring():

if(convert_to_wstring(convert_to_string(ws)) == ws)
    happy_days();

如果出现了什么,它是无损的(至少对于你的代码点而言)。

这不是最有效的解决方案,但应该允许您根据自己喜欢的转换例程进行构建。

// Round-trip and see if we lose anything
bool check_ws2s(const std::wstring& wstr)
{
    return (s2ws(ws2s(str)) == wstr);
}

How to convert wstring into string?使用@ dk123对C ++ 11的转换(在此处提升他的回答https://stackoverflow.com/a/18374698/257090

wstring s2ws(const std::string& str)
{
    typedef std::codecvt_utf8<wchar_t> convert_typeX;
    std::wstring_convert<convert_typeX, wchar_t> converterX;

    return converterX.from_bytes(str);
}

string ws2s(const std::wstring& wstr)
{
    typedef std::codecvt_utf8<wchar_t> convert_typeX;
    std::wstring_convert<convert_typeX, wchar_t> converterX;

    return converterX.to_bytes(wstr);
}

注意,如果你的转换想法是将宽字符截断为字符,那么只需迭代并检查每个宽字符值是否适合char。这可能会这样做。

警告:不适合多字节编码。

for(wchar_t& wc: ws) {
    if(wc > static_cast<char>::(wc))
        return false;
}
return true;

或者:

// Could use a narrowing cast comparison, but this avoids any warnings
for(wchar_t& wc: ws) {
    if(wc > std::numeric_limits<char>::max())
        return false;
}
return true;

FWIW,在Win32中,有一些转换例程接受WC_ERR_INVALID_CHARS参数,该参数告诉例程失败而不是静默丢弃代码点。当然是非标准的解决方案。

示例:WideCharToMultiByte()

http://msdn.microsoft.com/en-us/library/windows/desktop/dd374130(v=vs.85).aspx