我知道有关于 utf-8 的各种问题,主要是关于操作 utf-8 “字符串”之类对象的库。
然而,我正在开发一个“国际化”项目(一个网站,我在其中编写了 c++ 后端...不要问),即使我们处理 utf-8,我们实际上也不需要这样的库。大多数时候,简单的 std::string 方法或 STL 算法就足以满足我们的需求,实际上这就是使用 utf-8 的首要目标。
所以,我在这里寻找的是大写“又快又脏”您知道的与存储为 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());
}
事实上,当我需要字符数以外的任何内容时,我还没有遇到过这样的用例,并且 std::string 或 STL 算法不免费提供,因为:
- 排序按预期进行
- 单词的任何部分都不能与一个单词或另一个单词的一部分混淆
我想知道您是否还有其他类似的技巧,无论是用于计数还是用于其他简单的任务。
我再说一遍,我知道ICU http://site.icu-project.org/ and Utf8-CPP http://utfcpp.sourceforge.net/,但我对它们不感兴趣,因为我不需要成熟的处理(事实上我从来不需要比字符数更多的处理)。
我还重复一遍,我对处理 char* 不感兴趣,它们已经过时了。
好吧,这个肮脏的伎俩是行不通的。
首先,在此之后 mask 的值是多少:
const unsigned char mask = 0x11000000;
const unsigned char notUtf8Begin = 0x10000000;
也许您正在将十六进制表示与二进制混合。
其次,正如您在 utf-8 编码中正确所说的那样,一个字符可能有几个字节长。
std::count_if 将迭代 UTF8 序列中的所有字节。
但您实际需要的是查看每个字符的前导字节并跳过其余字节,直到下一个字符出现。
实现执行计算和跳跃的单个循环并不困难
使用简单掩码表作为前导字节。
最后,您将获得相同的 O(n) 来检查字符,并且它将适用于每个 UTF8 字符串。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)