【问题标题】:c++ making a unicode char from a stringc ++从字符串制作unicode char
【发布时间】:2015-01-19 20:28:41
【问题描述】:

我有一个这样的字符串

string s = "0081";

我需要像这样制作一个字符串

string c = "\u0081"  

如何从长度为 4 的原始字符串中生成长度为 1 的字符串?

编辑: 我的错误,“\u0081”不是字符(1 字节)而是 2 字节字符/字符串? 所以我输入的是二进制 1000 0001,即 0x81,这就是我的字符串“0081”的来源。 从这个 0x81 到字符串 c = "\u0081" 会更容易吗? 感谢大家的帮助

【问题讨论】:

  • 您是否尝试过完成它?你是怎么失败的?你确定你只想要更小的代码点0x10000
  • 如果你做类似字符串 c = "\u"+"0081";你得到一个错误,这是一个不完整的通用字符名称 \u 因为 c 是一个 1 个字符的字符串,你是否尝试类似 c.replace(0,1,"9");您只需替换所有内容,您就没有 \uXXXX 了,只有“9” 我无法从 4 个字符串“0081”中定义一个字符(\u0081)
  • 你没有,你得到一个错误,不能添加两个指向const char的指针。
  • 你试过string c = "\u0081"吗?我想你会发现它 not 是一个 1 字符的字符串。例如。 ideone.com/Ok7wnl
  • @MarkRansom:取决于您使用的“字符”定义。这让 unicode 变得如此有趣。

标签: c++ string utf-8 char


【解决方案1】:

这是整个过程,基于我在其他地方的评论中链接到的一些代码。

string s = "0081";
long codepoint = strtol(s.c_str(), NULL, 16);
string c = CodepointToUTF8(codepoint);

std::string CodepointToUTF8(long 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;
}

请注意,此代码不会进行任何错误检查,因此如果您传递一个无效的代码点,您将返回一个无效的字符串。

【讨论】:

  • 好的哇,这实际上工作得很好,请问我必须学习什么才能理解为什么这样工作?非常感谢您的帮助!
  • @mlf 你需要了解 UTF-8 是如何组合在一起的:en.wikipedia.org/wiki/UTF-8#Description
【解决方案2】:

给你:

unsigned int x;
std::stringstream ss;
ss << std::hex << "1081";
ss >> x;

wchar_t wc1 = x;
wchar_t wc2 = L'\u1081';

assert(wc1 == wc2);

std::wstring ws(1, wc);

【讨论】:

  • 他想要 UTF-8,所以没有香蕉。无论如何,你确定他不想要完整的 unicode 代码点吗?
  • @Deduplicator idk,我只是向他展示了如何“从长度为 4 的原始字符串中制作长度为 1 的字符串”
  • 您没有向他展示如何制作长度为 1 的字符串。您制作了一个 wchar_t,它甚至与 wstring 不同。您可以从wchar_t 轻松创建wstring。使用strtol 比使用 std::stringstream:std::wstring ws(1, wchar_t(strtol("1081", 0, 16)) 玩游戏更容易。然而,问题是在 UTF-8 中产生一个 string
  • @rici:我只是将其视为不了解关键区别的人围绕任何有关 unicode 的问题的标准混淆。所以,他的意思可能是 1 个 unicode 字符(无论他认为是代码点还是字素)。
  • 它是 UTF-8。 “\u1081”是三字节序列e1 82 81。 (U+1081 MYANMAR LETTER SHAN HA,以防有人感兴趣)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-27
  • 1970-01-01
  • 2014-06-12
  • 2018-09-18
  • 1970-01-01
  • 2017-07-08
相关资源
最近更新 更多