如果必须包含西里尔字符,如何将char *转换为std :: string?

时间:2019-08-13 09:29:32

标签: c++ encoding

我正在使用C库分析MS Excel文件。阅读函数返回char *字符串,我必须将其转换为std :: string。问题是我的文件包含西里尔符号,所以我得到了像“ Сделка”这样的字符串(而不是“Сделка”)

我尝试使用std :: wstring,但这最终破坏了字符。我还尝试使用Notepad ++还原字符,并且可以正常工作:将输出字符串粘贴到新文档中,然后按“在UTF8中编码”会显示正确的单词,但是我在代码中进行的尝试均未成功。因此,似乎chsr *字符串是ANSI字符串,而我想要的std :: string是UTF8字符串,但我发现的所有算法都不起作用。

我的代码片段

char* value;
while ((value = xlsxioread_sheet_next_cell(sheet)) != NULL)
{
    std::string str(value);
    std::cout << str << " ";
}

在main()里面,我有

SetConsoleOutputCP(1251);

目标是使用char *字符串制作一个包含西里尔字母的std :: string。

注意:

// works fine
std::string str = "Абвгдеж"; // str contains Абвгдеж
std::cout << str; // outputs Абвгдеж

2 个答案:

答案 0 :(得分:3)

如果字符串是utf8 ,则需要例如将语言环境设置为utf8:

std::setlocale(LC_ALL, "en_US.utf8");
std::cout << "Test: " << utf8str << std::endl;

答案 1 :(得分:1)

只需弄清楚我必须将UTF8字符串转换为ANSI字符串并使用正确的代码页(在这种情况下为Windows1251)即可达到目标。可以使用我在互联网上找到的以下代码来完成

string UTF8ToANSI(string s)
{
    BSTR    bstrWide;
    char*   pszAnsi;
    int     nLength;
    const char *pszCode = s.c_str();

    nLength = MultiByteToWideChar(CP_UTF8, 0, pszCode, strlen(pszCode) + 1, NULL, NULL);
    bstrWide = SysAllocStringLen(NULL, nLength);

    MultiByteToWideChar(CP_UTF8, 0, pszCode, strlen(pszCode) + 1, bstrWide, nLength);

    nLength = WideCharToMultiByte(CP_ACP, 0, bstrWide, -1, NULL, 0, NULL, NULL);
    pszAnsi = new char[nLength];

    WideCharToMultiByte(CP_ACP, 0, bstrWide, -1, pszAnsi, nLength, NULL, NULL);
    SysFreeString(bstrWide);

    string r(pszAnsi);
    delete[] pszAnsi;
    return r;
}

这个问题有点愚蠢,但我认为这对某人可能有用。也感谢@ Ville-Valtteri的帮助

编辑: 您可能需要将ANSI Win1251字符串转换回UTF8字符串。可以使用我在互联网上也找到的以下代码来完成此操作:

std::string ANSIToUTF8(std::string str)
{
    std::string res;
    int result_u, result_c;
    result_u = MultiByteToWideChar(1251, 0, str.c_str(), -1, 0, 0);
    if (!result_u) { return 0; }
    wchar_t *ures = new wchar_t[result_u];
    if (!MultiByteToWideChar(1251, 0, str.c_str(), -1, ures, result_u)) {
        delete[] ures;
        return 0;
    }
    result_c = WideCharToMultiByte(65001, 0, ures, -1, 0, 0, 0, 0);
    if (!result_c) {
        delete[] ures;
        return 0;
    }
    char *cres = new char[result_c];
    if (!WideCharToMultiByte(65001, 0, ures, -1, cres, result_c, 0, 0)) {
        delete[] cres;
        return 0;
    }
    delete[] ures;
    res.append(cres);
    delete[] cres;
    return res;
}