【问题标题】:How to parse std::string containing unicode literals?如何解析包含 unicode 文字的 std::string?
【发布时间】:2020-08-12 20:02:53
【问题描述】:

我有std::string,它存储以 UTF 编码的字符。示例:

std::string a = "\\u00c1\\u00c4\\u00d3";

请注意,a 的长度为 18(3 个字符,每个 UTF 字符有 6 个 ASCII 符号)。

问题:如何将a 转换为只有3 个字符的C++ 字符串?是否有任何标准功能(库)可以做到这一点?

【问题讨论】:

  • 请指定操作系统。 wstring在不同的系统中是不同的,有些系统对此有特定的功能。
  • 它是complicated。您可能需要ICU 或操作系统支持。

标签: c++ unicode stl ascii


【解决方案1】:

标准 C++ 库中没有任何内容可以自动为您处理这种转换。您将不得不自己解析此字符串,手动将每个 6 字符 "\uXXXX" 子字符串转换为 1 字符值 0xXXXX,然后您可以根据需要将其存储到 std::wstringstd::u16string 中。

例如:

std::string a = "\\u00c1\\u00c4\\u00d3";

std::wstring ws;
ws.reserve(a.size());

for(size_t i = 0; i < a.size();)
{
    char ch = a[i++];

    if ((ch == '\\') && (i < a.size()) && (a[i] == 'u'))
    {
        wchar_t wc = static_cast<wchar_t>(std::stoi(a.substr(++i, 4), nullptr, 16));
        i += 4;
        ws.push_back(wc);
    }
    else
    {
        // depending on the charset used for encoding the string,
        // this may or may not need to be decoded further...
        ws.push_back(static_cast<wchar_t>(ch));
    }
}

Live Demo

或者:

std::string a = "\\u00c1\\u00c4\\u00d3";
 
std::wstring ws;
ws.reserve(a.size());
 
size_t start = 0;
do
{
    size_t found = a.find("\\u", start);
    if (found == std::string::npos) break;

    if (start < found)
    {
        // depending on the charset used for encoding the string,
        // this may or may not need to be decoded further...
        ws.insert(ws.end(), a.begin()+start, a.begin()+found);
    }
 
    wchar_t wc = static_cast<wchar_t>(std::stoi(a.substr(found+2, 4), nullptr, 16));
    ws.push_back(wc);
 
    start = found + 6;
}
while (true);
 
if (start < a.size())
{
    // depending on the charset used for encoding the string,
    // this may or may not need to be decoded further...
    ws.insert(ws.end(), a.begin()+start, a.end());
}

Live Demo

否则,请使用已经为您完成此类翻译的第三方库。

【讨论】:

    猜你喜欢
    • 2011-02-09
    • 2018-06-19
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 2012-12-24
    • 1970-01-01
    相关资源
    最近更新 更多