【发布时间】:2010-12-02 18:00:17
【问题描述】:
我知道有很多关于 utf-8 的问题,主要是关于库来操作 utf-8 'string' 之类的对象。
但是,我正在从事一个“国际化”项目(一个网站,我在其中编写了一个 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 算法不免费提供,因为:
- 按预期进行排序
- 一个词的任何部分都不能混淆为一个词或另一个词的一部分
我想知道您是否还有其他类似的技巧,包括计数和其他简单任务。
我再说一遍,我知道 ICU 和 Utf8-CPP,但我对它们不感兴趣,因为我不需要全面的治疗(事实上我从来不需要超过字符数)。
我还要重申,我对处理 char* 不感兴趣,它们已经过时了。
【问题讨论】:
-
所以组合变音符号对你来说并不重要?这很可悲。根据您的计数,它们可能是字符,但它们不会占用更多空间。实际上,任何组合字符。或零宽度空格。排序是否按预期工作?你希望做什么?当您故意不使用 Unicode(某种字节数组除外)时,任何特定于语言环境的排序如何知道排序规则。
-
查看我的编辑,我的应用程序是网站的后端,因此语言环境掌握在浏览器手中。我们还没有遇到过组合字符的问题,我听说过但没见过,你在哪些语言中遇到过?
-
对非英文文本不起作用的几个用例:排序、大小写折叠、匹配(例如德语 ß 和 ss)。
-
那么您的意思是,只要您不希望您的 unicode 文本表现得像 unicode,那么如果您不将其视为 unicode,它就会按预期工作?我的,这是一个惊喜。但我为你的非英语用户哭泣。
-
平心而论,如果您将 UTF-16 或代码点直接存储到
wchar_t中,则同样会发生忽略组合变音符号的情况。使用 UTF-8 和char不会使问题变得更糟。