UTF-8在C ++:快速和肮脏的诡计(Utf-8 in c++: quick & dirty tr

2019-08-17 02:21发布

我知道有过关于UTF-8的各种问题,主要是关于库处理UTF-8“串”状物体。

不过,我工作的一个“国际化”项目(一个网站,该网站的我的代码是C ++后端......不要问),甚至如果我们处理UTF-8,我们并不需要实际上可以这样的库。 大多数时候普通的std :: string方法或STL算法是非常足够满足我们的需要,事实上这是摆在首位使用UTF-8的目标。

所以,我在找这里是你知道的相关UTF-8存储的std :: string(没有为const char *“快速和肮脏的”招数资本化,我不关心C风格的代码说真的,我有更重要的事情不是经常担心我的缓冲大小)的事情。

例如,这里是一个“快速和肮脏的”绝招获得的字符数(这是很有必要知道它是否适合你的显示框):

#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算法否则不提供免费的,因为一个用例:

  • 排序按预期工作
  • 没有一个词的一部分可以被混淆另一个单词的单词或部分

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

Answer 1:

嗯,这使坏将无法正常工作。 首先,什么是面膜后,这个值:

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

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

其次,当你在UTF-8编码正确地说,一个字符可能是几个字节长。 的std :: count_if将通过在UTF8序列的所有字节进行迭代。 但是你真正需要的是看领导字节为每个字符,并跳过休息,直到下一个字符来。

这不会是很难实现单周期,这不计算和雀跃着使用简单的面膜台领导字节。

在最后你会得到相同的O(n)的检查字符,它会与每一个UTF8字符串工作。



Answer 2:

排序UTF_8为二进制不会在排序“统一”的顺序。 BOCU-1会。 正如有人说,你的“预期”对于非英语内容相当低杠。



Answer 3:

我们处理它也像这样OpenLieroX (这是真的没事在一场比赛中,我认为)。

我们有一帮这样的UTF-8的std ::串有用的功能/算法。 见Unicode.h和Unicode.cpp 。 例如,有UTF8迭代器,一些简单的处理运算符(插入或删除),上/下转换的情况下,情况下独立搜索等

但是,不要指望这些功能是总是正确的。 例如,他们并不真正了解结合变音符号或可能不同的方式来编码相同的文字。



文章来源: Utf-8 in c++: quick & dirty tricks
标签: c++ utf-8