我需要读取带有 unicode 转义的标准 ascii 样式字符串,并将其转换为包含 utf8 编码等效项的 std::string。因此,例如“\u03a0”(一个带有 6 个字符的 std::string)应该被转换为带有两个字符的 std::string,分别为 0xce、0xa0,以原始二进制表示。
如果使用 icu 或 boost 有一个简单的答案,我会很高兴,但我找不到。
(这类似于将 Unicode 字符串转换为转义的 ASCII 字符串,但请注意,我最终需要达到 UTF8 编码。如果我们可以使用 Unicode 作为中间步骤就好了。)
尝试这样的事情:
std::string to_utf8(uint32_t cp)
{
    /*
    if using C++11 or later, you can do this:
    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> conv;
    return conv.to_bytes( (char32_t)cp );
    Otherwise...
    */
    std::string result;
    int count;
    if (cp <= 0x007F)
        count = 1
    else if (cp <= 0x07FF)
        count = 2;
    else if (cp <= 0xFFFF)
        count = 3;
    else if (cp <= 0x10FFFF)
        count = 4;
    else
        return result; // or throw an exception
    result.resize(count);
    if (count > 1)
    {
        for (int i = count-1; i > 0; --i)
        {
            result[i] = (char) (0x80 | (cp & 0x3F));
            cp >>= 6;
        }
        for (int i = 0; i < count; ++i)
            cp |= (1 << (7-i));
    }
    result[0] = (char) cp;
    return result;
}
std::string str = ...; // "\\u03a0"
std::string::size_type startIdx = 0;
do
{
    startIdx = str.find("\\u", startIdx);
    if (startIdx == std::string::npos) break;
    std::string::size_type endIdx = str.find_first_not_of("0123456789abcdefABCDEF", startIdx+2);
    if (endIdx == std::string::npos) break;
    std::string tmpStr = str.substr(startIdx+2, endIdx-(startIdx+2));
    std::istringstream iss(tmpStr);
    uint32_t cp;
    if (iss >> std::hex >> cp)
    {
        std::string utf8 = to_utf8(cp);
        str.replace(startIdx, 2+tmpStr.length(), utf8);
        startIdx += utf8.length();
    }
    else
        startIdx += 2;
}
while (true);