从终端C ++

时间:2017-03-27 21:27:22

标签: c++ string unicode

将包含unicode字符的字符串打印到终端时,unicode字符会正确显示。但是当我尝试将unicode char分隔成一个字符串并将其打印出来时,它会打印为"?"。如何从字符串中提取unicode char并将其放在一个新字符串中而不会丢失其unicode内存?

text是一个全局的std :: string

这就是我将unicode char拉出来的方式:

stringstream ss;
string ret = "";
ss << text[index];
ss >> ret;

此外,我不能使用wchar,wstring或任何与unicode有关的std库。

2 个答案:

答案 0 :(得分:1)

ss << text[index];

我的猜测是text是一个C String或其他实际上使用字节(在C和C ++中称为char)作为存储的东西。所以你的[]索引操作不会给你整个unicode代码点,只提供它的一个字节。

编辑您已添加

  

“我不能使用......任何与unicode有关的标准库”

这是废话要求。这意味着你必须重新实现unicode功能,这是a)巨大的东西和b)臭虫的bringer。所以,对于所有正确的事情:你使用std::stringstream,你也可以使用宽字符等。

答案 1 :(得分:1)

假设您使用的是UTF-8,问题是个别UTF-8个字符可以占据14字节(理论上6)。

为了遍历它们,您需要计算每个字符的大小。以下代码使用一个简单的表格,但您也可以通过位操作获得创意:

#include <string>
#include <vector>
#include <iostream>

// return individual utf-8 chars as a vector of strings
std::vector<std::string> utf8_split_chars(std::string const& s)
{
    // table to get the size of a utf-8 character
    static const char u8char_size[] =
    {
          1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
        , 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
        , 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
        , 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
        , 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
        , 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
        , 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
        , 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
        , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        , 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
        , 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
        , 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
        , 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0
    };

    std::vector<std::string> utf8_chars;

    // increment the index i by the size of each utf-8 char
    for(auto i = 0U; i < s.size(); i += u8char_size[(unsigned char)s[i]])
    {
        utf8_chars.emplace_back(&s[i], u8char_size[(unsigned char)s[i]]);
    }

    return utf8_chars;
}

int main()
{
    std::string s = u8"建造 otoño κάτω";

    std::cout << "s: " << s <<" " << s.size() << " bytes" << '\n';

    auto chars = utf8_split_chars(s);

    for(auto const& c: chars)
        std::cout << "c: " << c << '\n';
}

<强>输出:

s: 建造 otoño κάτω 22 bytes
c: 建
c: 造
c:  
c: o
c: t
c: o
c: ñ
c: o
c:  
c: κ
c: ά
c: τ
c: ω