0

我想在不使用mbstowcs(). 在 iOS 和 Windows 上,这可以完美运行。然而,在 Android 上,mbstowcs 似乎完全按照字面意思进行转换,一对一。即使使用不同的变体setlocale(),我也无法成功转换。

我最终可能只是通过复制 1 个字节在 Android 上手动转换它,然后用零填充其余部分。但这适用于 ASCII 吗?UTF-32/Unicode 的前 255 个字符是否与 ASCII(ISO 8859-1/ISO Latin-1)字符集相同?

4

3 回答 3

3

为了使想法更清晰:

  • ASCII 是一种字符编码,使用 0..127 中的值对单个字符进行编码。
  • Latin-1 是另一个字符集,它通过使用 128..255 中的值对自己的字符进行编码来扩展 ASCII。

事实上,大多数架构字节是 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)。

于 2013-08-07T16:13:29.543 回答
1

如果您不介意使用 STL 依赖项并使用stringandwstring而不是原始指针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 上进行了测试。

于 2013-08-07T16:13:18.703 回答
0

可以使用以下代码缩短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);
}

演示

于 2013-08-08T00:53:10.880 回答