首页 > 解决方案 > 如何从(w)字符串中获取 unicode char 的 utf-8 int 值?

问题描述

情况

我需要一个函数,它需要一个字符串并将所有非 ascii 字符编码为 utf-8 作为十六进制数并用它替换它。

例如,像“djvӷdio”这样的词中的ӷ应该替换为“d3b7”,而其余部分保持不变。

Explanation:
ӷ equals int 54199 and in hexadecimal d3b7
djvӷdio --> djvd3b7dio

我已经有一个返回 int 十六进制值的函数。

我的机器

我的想法

1. 想法

std::string encode_utf8(const std::string &str);

通过使用上面的函数,我遍历包含 unicode 的整个字符串,如果当前 char 不是 ascii,我将其替换为十六进制值。

问题:

使用 unicode 遍历字符串并不聪明,因为 unicode char 与普通 char 不同,最多由 4 个字节组成。因此,一个unicode 字符可以被视为输出垃圾的多个字符。简单来说,字符串不能被索引。

2.想法

std::string encode_utf8(const std::wstring &wstr);

同样,我用 unicode 字符遍历整个字符串,如果当前字符不是 ascii,我用它的十六进制值替换它。

问题:

索引现在有效,但它返回一个带有相应 utf-32 数字的 wchar_t,但我绝对需要 utf-8 数字。


如何从可以获取 utf-8 十进制数的字符串中获取字符?

标签: c++unicodeutf

解决方案


您的输入字符串是 UTF8 编码的,这意味着每个字符都由 1 到 4 个字节编码。您不能只扫描字符串并转换它们,除非您的循环了解 Unicode 字符是如何以 UTF8 编码的。

您需要一个 UTF8 解码器。

幸运的是,如果您只需要解码,您可以使用真正轻量级的。UTF8-CPP几乎是一个标头,并且具有为您提供单个 Unicode 字符的功能。utf8::next会喂给你uint32_t(“最大”字符的代码点适合这种类型的对象)。现在您可以简单地查看该值是否小于 128:如果是,则强制转换char并追加;如果不是,请以您认为合适的任何方式序列化整数。

不过,我恳请您考虑一下这是否真的是您想要做的。您的输出将是模棱两可的。无法确定其中的一堆数字是实际数字,还是某些非 ASCII 字符的表示。为什么不坚持使用原始的 UTF8 编码,或者使用 HTML 实体编码或引用打印?这些编码被广泛理解和广泛支持。


推荐阅读