C++ 处理std::wstring和std::string之间的UTF-8编码字符串

C++ 处理std::wstring和std::string之间的UTF-8编码字符串,c++,unicode,utf-8,C++,Unicode,Utf 8,我使用两个库,一个在std::wstring中存储UTF-8字符串,另一个在std::string中存储字符串(UTF-8) 在两个库之间传递字符串的最佳/有效方法是什么。 我现在使用Visual C++ V9 Express在Windows上,但更喜欢便携式解决方案。 < P>假设你是UTF-16,而不是UTF-8,对于 STD::WScING/,你必须对一个库中的字符串进行编码/解码。我不确定STL是否/提供了什么,但您可以使用Windows自己的MultiByteToWideChar()和

我使用两个库,一个在
std::wstring
中存储UTF-8字符串,另一个在
std::string
中存储字符串(UTF-8)
在两个库之间传递字符串的最佳/有效方法是什么。

我现在使用Visual C++ V9 Express在Windows上,但更喜欢便携式解决方案。

< P>假设你是UTF-16,而不是UTF-8,对于<代码> STD::WScING/<代码>,你必须对一个库中的字符串进行编码/解码。我不确定STL是否/提供了什么,但您可以使用Windows自己的
MultiByteToWideChar()
WideCharToMultiByte()
函数,只需几行代码即可在UTF-8和UTF-16之间进行转换。然后,您可以将其包装到自己的函数中,以便在发现更便于移植的内容时替换逻辑,例如:

std::wstring Utf8ToUtf16(const std::string &s)
{
    std::wstring ret;
    int len = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.length(), NULL, 0);
    if (len > 0)
    {
      ret.resize(len);
      MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.length(), const_cast<wchar_t*>(ret.c_str()), len);
    }
    return ret;
}

std::string Utf16ToUtf8(const std::wstring &s)
{
    std::string ret;
    int len = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), s.length(), NULL, 0, NULL, NULL);
    if (len > 0)
    {
      ret.resize(len);
      WideCharToMultiByte(CP_UTF8, 0, s.c_str(), s.length(), const_cast<char*>(ret.c_str()), len, NULL, NULL);
    }
    return ret;
}
std::wstring Utf8ToUtf16(const std::string&s)
{
std::WST环网;
int len=MultiByteToWideChar(CP_UTF8,0,s.c_str(),s.length(),NULL,0);
如果(len>0)
{
重新调整大小(len);
MultiByteToWideChar(CP_UTF8,0,s.c_str(),s.length(),const_cast(ret.c_str()),len);
}
返回ret;
}
标准::字符串UTF16TUF8(常数标准::wstring&s)
{
std::字符串ret;
int len=WideCharToMultiByte(CP_UTF8,0,s.c_str(),s.length(),NULL,0,NULL,NULL);
如果(len>0)
{
重新调整大小(len);
宽图表多字节(CP_UTF8,0,s.c_str(),s.length(),const_cast(ret.c_str()),len,NULL,NULL);
}
返回ret;
}

考虑一下。它是可移植的,在编码之间有很多转换器

当你说“在std::wstring中存储UTF-8字符串”时,你到底指的是什么?你是说UTF-16吗?std::wstring不适合存储UTF-8八位字节(但std::string是)。@Remy Lebeau它是一个ODBC库,用于从数据库检索UTF-8数据并在std::wstring中传递数据。我真的不知道数据实际上是如何存储在库中的。库如何在内部处理数据并不重要。重要的是它如何向代码传递数据。如果它使用的是
std::wstring
,那么它很可能使用/期望使用UTF-16。这是有道理的,因为UTF-8和UTF-16只是相同Unicode字符集的不同编码。数据库可以使用UTF-8以外的任何字符集,ODBC可能会在内部处理它,并且在向您传递数据或从您传递数据时仍然使用UTF-16以保持一致性。如果您使用ODBC库检索ASCII范围之外的字符,例如
a
,wstring[0]的十进制或十六进制值是多少请注意,这是特定于Windows的,但UTF-16在这里希望表示Windows。不会编译为
c_str
返回常量c字符串。但是+1表示正确。UTF-16不是特定于Windows的。唯一特定于Windows的部分是使用的API函数。就像我说的,这只是为了演示如何做。当OP找到一个更可移植的解决方案时,他/她可以替换API函数,而不必重写他/她的其余代码。我现在添加了两个
const\u cast
cast。UTF-16本身不是特定于Windows的,但是
wchar\u t
是UTF-16的假设是特定于Windows的。对于我当前的需求来说太大了。我的程序小于400KB,静态链接到运行时。ICU的大小可能会增加一倍以上,我不确定是否可以静态链接到它。如果不是ICU,则
iconv
。这甚至是POSIX。