2009-09-30 49 views
11

我知道有关于utf-8的各种问题,主要是关于图书馆来处理像对象一样的utf-8'字符串'。我正在研究一个'国际化'的项目(一个网站,我编写了一个C++后端...不问),即使我们处理utf-8,我们也不需要这样做库。大多数情况下,普通的std :: string方法或STL算法都足以满足我们的需求,实际上这是首先使用utf-8的目标。在c + +的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算法否则不提供免费的,因为:

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

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

+9

那么结合变音符号对你无关紧要?这很伤心。他们可能是你算的人物,但他们不占用更多的空间。实际上任何组合角色。或零宽度的空间。排序如预期般运作?你能指望什么?如果有意不使用Unicode(除非是某种字节数组),那么任何特定于语言环境的排序如何知道排序规则。 – Joey 2009-09-30 18:02:02

+0

查看我的编辑,我的应用程序是网站的后端,因此语言环境在浏览器中。我们从来没有遇到过结合角色的问题,我听说过他们,但从未见过他们,你遇到过哪些语言? – 2009-09-30 18:14:45

+0

几个不适用于非英文文本的用例:排序,案例折叠,匹配(例如德语ß和ss)。 – 2009-09-30 18:26:12

回答

5

那么这个肮脏的把戏将无法正常工作。 一,什么是面膜的值之后这样的:

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

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

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

要使用简单掩码表作为前导字节,执行计算并向前跳转 并不困难。

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

+0

是的,把我的面具弄混了,对不起。但是,除了组合变音符号问题之外,count_if仍然正确。 – 2009-10-02 12:23:56

+0

我正在研究一个utf8字符串类,其中++会正确地遍历宽代码点,并放弃从字节跳转到字节的偏移量数组。它向前发展很好,但因为它没有提供任何好处。迂回代码更容易维护。 – jmucchiello 2009-10-08 19:34:17

1

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

0

我们在OpenLieroX(我认为这真的很好)中也是这样处理的。

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

但是,不要指望这些函数总是正确的。例如,他们不知道如何组合符号或可能的不同方式来编码相同的文本。

相关问题