繁体   English   中英

C ++中的Utf-8:快速而肮脏的技巧

[英]Utf-8 in c++: quick & dirty tricks

我知道有关于utf-8的各种问题,主要是关于库来操纵utf-8'字符串'之类的对象。

但是,我正在开发一个'国际化'项目(一个网站,我编写一个c ++后端代码......不要问),即使我们处理utf-8,我们也不需要这样的库。 大多数情况下,普通的std :: string方法或STL算法足以满足我们的需求,实际上这是首先使用utf-8的目标。

所以,我在这里寻找的是一个大概的“Quick&Dirty”技巧,你知道与存储为std :: string的utf-8相关(没有const char *,我不关心c风格的代码真的,我有更好的事情要做,而不是经常担心我的缓冲区大小)。

例如,这里有一个“Quick&Dirty”技巧来获取字符数(这对于知道它是否适合您的显示框很有用):

#include <string>
#include <algorithm>

// Let's remember than in utf-8 encoding, a character may be
// 1 byte: '0.......'
// 2 bytes: '110.....' '10......'
// 3 bytes: '1110....' '10......' '10......'
// 4 bytes: '11110...' '10......' '10......' '10......'
// Therefore '10......' is not the beginning of a character ;)

const unsigned char mask = 0xC0;
const unsigned char notUtf8Begin = 0x80;

struct Utf8Begin
{
  bool operator(char c) const { return (c & mask) != notUtf8Begin; }
};

// Let's count
size_t countUtf8Characters(const std::string& s)
{
  return std::count_if(s.begin(), s.end(), Utf8Begin());
}

事实上,当我需要除了字符数以外的任何东西并且std :: string或STL算法不提供免费提供时,我还没有遇到一个用例:

  • 排序按预期工作
  • 一个单词的任何部分都不能被混淆为一个单词或另一个单词的一部分

我想知道你是否有其他类似的技巧,包括计数和其他简单的任务。
我再说一遍,我知道ICUUtf8-CPP ,但我对它们不感兴趣,因为我不需要一个完整的治疗(实际上我从来没有需要超过字符数)。
我也重申,我对治疗char *不感兴趣,他们是老式的。

那么这个肮脏的把戏是行不通的。 首先,在此之后掩码的价值是什么:

   const unsigned char mask = 0x11000000;
   const unsigned char notUtf8Begin = 0x10000000;

也许你将十六进制表示与二进制混合。

其次,正如你在utf-8编码中正确说的那样,一个字符可能是几个字节长。 std :: count_if将遍历UTF8序列中的所有字节。 但实际需要的是查看每个字符的前导字节并跳过其余字符,直到下一个字符出现。

实现计算并使用简单掩码表进行前导字节的单个循环并不难。

最后,你得到相同的O(n)来检查字符,它将适用于每个UTF8字符串。

将UTF_8排序为二进制文件不会按“Unicode”顺序排序。 BOCU-1会。 如前所述,你的“预期”对于非英语内容来说是一个相当低的标准。

我们在OpenLieroX中也是这样处理的(我认为这在游戏中非常好)。

我们为这样的UTF-8 std :: strings提供了许多有用的函数/算法。 请参见Unicode.hUnicode.cpp 例如,有UTF8迭代器,一些简单的操作操作符(插入或擦除),大小写转换,大小写独立搜索等。

但是不要指望这些功能总是正确的。 例如,他们并不真正知道组合变音符号或可能的不同方法来编码相同的文本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM