如何在C ++中将类似“ \ 320 \ 272 \ 320 \ 276 \ 320 \ 274 ...”的文本转换为std :: wstring?

时间:2018-07-04 16:42:58

标签: c++ utf-8

我正在处理一个处理来自Ubuntu的消息的代码,其中一些消息包含,例如:

localhost sshd 1658--来自172.28的无效用户\ 320 \ 272 \ 320 \ 276 \ 320 \ 274 \ 320 \ 274 \ 321 \ 320 \ 275 \ 320 \ 270 \ 320 \ 267 \ 320 \ 274。 60.28端口50712]

其中“ \ 320 \ 272 \ 320 \ 276 \ 320 \ 274 \ 320 \ 274 \ 321 \ 320 \ 275 \ 320 \ 270 \ 320 \ 267 \ 320 \ 274”是最初使用俄语的用户名。如何将其转换为std :: wstring?

2 个答案:

答案 0 :(得分:2)

反斜杠后的数字是西里尔字母的UTF-8字节序列值,每个字节表示为一个八进制数字。

例如,您可以使用正则表达式替换将每个\ooo替换为其值,以便获得实际的UTF-8字符串:

See it on Wandbox

#include <iostream>
#include <string>
#include <boost/regex.hpp>

int main()
{
    std::string const source = R"(Invalid user \320\272\320\276\320\274\320\274\321\320\275\320\270\320\267\320\274 from 172.28.60.28 port 50712)";
    boost::regex const re(R"(\\\d\d\d)");

    auto const replacer = [](boost::smatch const& match, auto it) {
        auto const byteVal = std::stoi(&match[0].str()[1], 0, 8);
        *it = static_cast<char>(byteVal);
        return ++it;
    };
    std::string const out = boost::regex_replace(source, re, replacer);

    std::cout << out << std::endl;
    return EXIT_SUCCESS;
}

如果确实需要,您可以使用以下方法将此std::string转换为std::wstringThomas的方法。

答案 1 :(得分:1)

如果您有一个包含UTF-8代码点的std::string,并且希望将其转换为std::wstring,则可以使用std::codecvt_utf8方面和std::wstring_convert类模板:

#include <locale>
std::wstring convert(const std::string& utf8String) {
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter{};
    return converter.from_bytes(utf8String);
}

结果std::wstring的格式将是UCS2(在Windows平台上)或UCS4(在大多数非Windows平台上)。

请注意,std::codecvt_utf8构面从C ++ 17开始不推荐使用,而是鼓励消费者依赖专门的unicode /文本处理库。但这现在就足够了。