如何在保留字符的同时加宽标准字符串?

时间:2018-07-12 20:00:32

标签: c++11 stdstring wchar-t

我具有一个将std::string更改为wchar_t*的功能。我当前的加宽功能看起来像这样

wchar_t* widen(const std::string& str){  
    wchar_t * dest = new wchar_t[str.size()+1];
    char * temp = new char[str.size()];
    for(int i=0;i<str.size();i++)
        dest[i] = str[i];
    dest[str.size()] = '\0';
    return dest;
}  

这对于标准字符来说很好用,但是(当我不能相信这以前不是问题)当我遇到á,é,í,ó,ú,ñ或ü这样的字符时,它会中断并且结果差别很大。
例如:我的str"Database Function: áFákéFúnctíóñü"的形式出现
但是dest最终显示为:"Database Function: £F£k←Fnct■￳￱"

如何在保持国际字符的同时从std::string变为wchar_t*

2 个答案:

答案 0 :(得分:3)

简短的回答:您不能。

更长的答案:std::string包含char个元素,该元素通常在前127个值中包含ASCII,而其他所有内容(“国际字符”)都在上面的值中(或否定的,如果{ {1}}已签名)。为了确定char字符串中的对应表示形式,您首先需要知道源字符串中的编码(可以是ISO-8859-15甚至UTF-8),而目标字符串中的编码(通常是UTF-16,UCS2或UTF-32),然后相应地进行转码。

答案 1 :(得分:0)

这取决于源是否使用旧的ANSI代码页或UTF8。对于ANSI代码页,您必须知道语言环境,并使用mbstowcs。对于UTF8,您可以使用codecvt_utf8_utf16转换为UTF16。但是,codecvt_utf8_utf16已过时,并且至今没有替代品。在Windows中,您可以使用WinAPI函数使转换更加可靠。

#include <iostream>
#include <string>
#include <codecvt>

std::wstring widen(const std::string& src)
{
    int len = src.size();
    std::wstring dst(len + 1, 0);
    mbstowcs(&dst[0], src.c_str(), len);
    return dst;
}

int main()
{
    //ANSI code page?
    std::string src = "áFákéFúnctíóñü";
    setlocale(LC_ALL, "en"); //English assumed
    std::wstring dst = widen(src);
    std::wcout << dst << "\n";

    //UTF8?
    src = u8"áFákéFúnctíóñü";
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convert;
    dst = convert.from_bytes(src);
    std::wcout << dst << "\n";

    return 0;
}