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

Mat*_* M. 11 c++ utf-8

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

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

所以,我在这里寻找的是一个大概的"Quick&Dirty"技巧,你知道与存储为std :: string的utf-8相关(没有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());
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

ale*_*xkr 5

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

   const unsigned char mask = 0x11000000;
   const unsigned char notUtf8Begin = 0x10000000;
Run Code Online (Sandbox Code Playgroud)

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

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

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

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