如何在不使用mbstowcs的情况下将C ++中的ASCII char *转换为wchar_t *?

时间:2013-08-07 15:42:53

标签: android c++ string unicode ascii

我想在Linux上将C ++中的ASCII char *转换为wchar_t *而不使用mbstowcs()。在iOS和Windows上,这非常有效。然而,在Android上,mbstowcs似乎可以一对一地完全转换。即使使用setlocale()的不同变体,我也无法成功转换。

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

3 个答案:

答案 0 :(得分: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)。

答案 1 :(得分:1)

如果您不介意使用STL依赖项并使用stringwstring而不是原始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;
}

这将执行逐个字符的转换,并且与平台无关。这已经在Windows上使用GCC 4.7.3和Visual C ++ 2012以及使用GCC 4.7.3在Linux上进行了测试。

答案 2 :(得分: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);
}

Demo