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

如何知道wstring是否可以安全地(无数据丢失)转换为字符串?,string,c++11,type-conversion,wstring,String,C++11,Type Conversion,Wstring,所以我已经知道如何将wstring转换为string() 但是,我想知道进行转换是否安全,这意味着wstring变量不包含string类型中不支持的任何字符。如果使用正确的编码,字符串可以保存任何数据。它们只是字节序列。但是您需要检查特定的编码/转换例程 应该只是一个往返的问题。许多事情的优雅解决方案 警告,伪代码,除非您这样做,否则不存在将\u转换为\u wstring()的文本: if(convert_to_wstring(convert_to_string(ws)) == ws)

所以我已经知道如何将
wstring
转换为
string
()


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

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

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

警告,伪代码,除非您这样做,否则不存在将\u转换为\u 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);
}
使用@dk123对C++11的转换(在这里对他的答案进行投票)

wstring s2ws(常量std::string&str)
{
typedef std::codevt_utf8 convert_typeX;
std::wstring_转换转换器x;
返回converterX.from_字节(str);
}
字符串ws2s(常量标准::wstr和wstr)
{
typedef std::codevt_utf8 convert_typeX;
std::wstring_转换转换器x;
将转换器x.返回到_字节(wstr);
}
注意,如果您的转换思想是将宽字符截断为字符,那么只需迭代并检查每个宽字符值是否适合一个字符。这可能就行了

警告:不适用于多字节编码

for(wchar_t& wc: ws) {
    if(wc > static_cast<char>::(wc))
        return false;
}
return true;
for(wchar\u t&wc:ws){
如果(wc>静态_cast::(wc))
返回false;
}
返回true;
或:

//可以使用缩小强制转换比较,但这样可以避免任何警告
用于(wchar_t&wc:ws){
如果(wc>std::numeric_limits::max())
返回false;
}
返回true;
FWIW,在Win32中,有一些转换例程接受参数
WC\u ERR\u INVALID\u CHARS
,该参数告诉例程失败,而不是自动删除代码点。当然是非标准的解决方案

示例:WideChartMultiByte()


只需使用您正在使用的任何标准方法(wcstombs或wstring\u convert)进行转换即可。您将返回实际转换的前缀的长度。如果它是整个wstring,则您已设置。如果不是,你确切地知道问题人物在哪里;当
wstring
变量具有
\0
字符时,我遇到一个问题,转换停止。因此,在这种情况下,目标
字符串可能比源
wstring
短。我没有用你的impl。因为我在运行它时在内存位置0x0021F044处得到异常:std::range\u错误。
。相反,我使用:
mbstowcs\u
。有什么建议吗?哪个方法给了你错误,用什么输入字符串?
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;