无符号整数作为UTF-8值

时间:2013-11-14 03:01:17

标签: c++ c++11 unicode utf-8

假设我有

uint32_t a(3084);

我想创建一个存储unicode字符U+3084的字符串,这意味着我应该取a的值并将其用作UTF8表/ charset中正确字符的坐标

现在,显然std::to_string()对我不起作用,标准中有很多函数可以在数值和char之间进行转换,我找不到任何给我UTF8支持并输出{的东西{1}}。

我想问一下我是否必须从头开始创建这个函数,或者C ++ 11标准中有一些东西可以帮助我;请注意,我的编译器(gcc / g ++ 4.8.1)不提供对std::string的完全支持。

4 个答案:

答案 0 :(得分:7)

这是一些不难转换为C的C ++代码。改编自older answer

std::string UnicodeToUTF8(unsigned int codepoint)
{
    std::string out;

    if (codepoint <= 0x7f)
        out.append(1, static_cast<char>(codepoint));
    else if (codepoint <= 0x7ff)
    {
        out.append(1, static_cast<char>(0xc0 | ((codepoint >> 6) & 0x1f)));
        out.append(1, static_cast<char>(0x80 | (codepoint & 0x3f)));
    }
    else if (codepoint <= 0xffff)
    {
        out.append(1, static_cast<char>(0xe0 | ((codepoint >> 12) & 0x0f)));
        out.append(1, static_cast<char>(0x80 | ((codepoint >> 6) & 0x3f)));
        out.append(1, static_cast<char>(0x80 | (codepoint & 0x3f)));
    }
    else
    {
        out.append(1, static_cast<char>(0xf0 | ((codepoint >> 18) & 0x07)));
        out.append(1, static_cast<char>(0x80 | ((codepoint >> 12) & 0x3f)));
        out.append(1, static_cast<char>(0x80 | ((codepoint >> 6) & 0x3f)));
        out.append(1, static_cast<char>(0x80 | (codepoint & 0x3f)));
    }
    return out;
}

答案 1 :(得分:5)

std::string_convert::to_bytes只为您提供单字符重载。

#include <iostream>
#include <string>
#include <locale>
#include <codecvt>
#include <iomanip>

// utility function for output
void hex_print(const std::string& s)
{
    std::cout << std::hex << std::setfill('0');
    for(unsigned char c : s)
        std::cout << std::setw(2) << static_cast<int>(c) << ' ';
    std::cout << std::dec << '\n';
}

int main()
{
    uint32_t a(3084);

    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> conv1;
    std::string u8str = conv1.to_bytes(a);
    std::cout << "UTF-8 conversion produced " << u8str.size() << " bytes:\n";
    hex_print(u8str);
}

我得到(使用libc ++)

$ ./test
UTF-8 conversion produced 3 bytes:
e0 b0 8c 

答案 2 :(得分:1)

C ++标准包含std::codecvt<char32_t, char, mbstate_t>方面,它根据22.4.1.4 [locale.codecvt]第3段在UTF-32和UTF-8之间进行转换。遗憾的是,std::codecvt<...>方面并不容易使用。在某些时候,讨论了过滤流缓冲区,它将采用代码转换的方式(标准C ++库需要为std::basic_filebuf<...>实现它们),但我看不到任何这些痕迹。

答案 3 :(得分:0)

auto s = u8"\343\202\204"; // Octal escaped representation of HIRAGANA LETTER YA
std::cout << s << std::endl;

打印

对我来说(使用g ++ 4.8.1)。正如您所期望的那样,s具有类型const char*,但我不知道这是否是实现定义的。不幸的是,就我所知,C ++对UTF8字符串的操作没有任何支持;为此,您需要使用像Glib::ustring这样的库。