【问题标题】:How to know if wstring can be safely (no data loss) converted to string?如何知道 wstring 是否可以安全(无数据丢失)转换为字符串?
【发布时间】:2014-12-21 15:18:05
【问题描述】:

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

但是,我想知道进行转换是否安全,这意味着wstring 变量确实包含string 类型不支持的任何字符。

【问题讨论】:

  • 只需使用您使用的任何标准方法(wcstombs 或 wstring_convert)进行转换。您将取回实际转换的前缀的长度。如果它是您的 wstring 的全部,那么您已经设置好了。如果不是,您就知道问题字符的确切位置。

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


【解决方案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);
}

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

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

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

【讨论】:

  • 也许你可以帮我;当wstring 变量具有\0 字符时,我遇到了一个问题,转换停止。所以在这种情况下,目标string 可能比源wstring 短。我没有使用你的 impl。因为我在运行它时得到exception: std::range_error at memory location 0x0021F044.。相反,我使用:mbstowcs_s。有什么建议吗?
  • 哪种方法给了你错误,输入字符串是什么?
猜你喜欢
  • 2012-08-20
  • 2012-08-17
  • 1970-01-01
  • 1970-01-01
  • 2011-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多