我想在不使用mbstowcs()
. 在 iOS 和 Windows 上,这可以完美运行。然而,在 Android 上,mbstowcs 似乎完全按照字面意思进行转换,一对一。即使使用不同的变体setlocale()
,我也无法成功转换。
我最终可能只是通过复制 1 个字节在 Android 上手动转换它,然后用零填充其余部分。但这适用于 ASCII 吗?UTF-32/Unicode 的前 255 个字符是否与 ASCII(ISO 8859-1/ISO Latin-1)字符集相同?
为了使想法更清晰:
事实上,大多数架构字节是 8 位,因此在以字节存储 ASCII 字符时仍有 128 个值可用。因此设计了几个不同的字符集来扩展 ASCII 的值,从 128..255 开始。快乐的意外,被称为Latin-1的那个被用于 Unicode 中的前 256 个代码点(如 BoBTFish 所指出的那样)。因此,如果一方面您知道使用 Latin-1 编码的字符字符串,您可以将每个值分配给 wchar_t(这将确保您的架构上的字节序正确“零填充”),它将是对应于相同字符的unicode 代码点的有效 wstring。然后,您的 wstring 的使用者必须将其内容解释为 unicode 代码点。
此外,一旦你不能保证原始字符串的编码是 Latin-1,你就会遇到问题。(例如,UTF-8 编码没有将逐字节映射到 Latin-1)。
如果您不介意使用 STL 依赖项并使用string
andwstring
而不是原始指针char *
和wchar_t *
指针,则可以使用如下函数来执行字符串转换:
template<typename TARGET, typename SOURCE>
TARGET convertString(const SOURCE &s)
{
TARGET result;
result.assign(s.begin(), s.end());
return result;
}
如下使用它:
#include <string>
#include <iostream>
using namespace std;
int main()
{
wstring wstr(L"HELLO WORLD");
string str(convertString<string, wstring>(wstr));
cout << str << endl;
return 0;
}
这将执行逐个字符的转换,并且与平台无关。这已经在使用 GCC 4.7.3 和 Visual C++ 2012 的 Windows 以及使用 GCC 4.7.3 的 Linux 上进行了测试。
可以使用以下代码缩短std::wstring_convert
:
#include <string>
#include <locale>
std::string convert(std::wstring str, std::locale loc = std::locale(),
std::mbstate_t state = std::mbstate_t())
{
const wchar_t* a; char *b;
std::string res;
res.resize(str.size());
auto bytes = std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(loc)
.out(state, &str[0], &str[str.size()], a, &res[0], &res[res.size()], b);
return res;
}
int main()
{
std::wstring a = L"abcdef";
std::string b = convert(a);
}