【问题标题】:how can I compare utf8 string such as persian words in c++?如何比较 utf8 字符串,例如 c++ 中的波斯语单词?
【发布时间】:2011-10-31 18:27:15
【问题描述】:

我想比较波斯语 (utf8) 中的字符串。我知道我必须使用 L"گل" 之类的东西,并且它必须保存在 wchar_t * 或 wstring 中。问题是当我通过函数 compare() 字符串进行比较时,我没有得到正确的结果。

【问题讨论】:

  • 你有 C++11(例如 GCC 4.6)吗?
  • 你的意思是比较相等,还是比较排序,或者只是什么?
  • 实际比较相等
  • 我正在使用 windows xp visual studio 2008

标签: c++ string encoding


【解决方案1】:

wchar_t 不适用于 UTF-8,但(取决于平台)通常是 UTF-16 或 UCS-32。如果您想使用 UTF-8,请使用普通的旧 char *string,以及它们的相等比较函数。如果您想要对人类有意义的排序,它会涉及更多内容(无论您使用哪种编码)。

【讨论】:

  • String.Compare 对两个 String 进行操作,而 String 没有来自 wchar 的构造函数,因此很可能您将 wchar 构造为错误的 char,并且您提前遇到了空终止,以及为什么您的比较失败 - 如果您使用 UTF-8 操作,您可以将所有内容存储为 char 并且所有内容都应该可以正常工作,除了“大于”和“小于”会给您带来问题,但您可能遇到了这些问题在 wchar 中也是如此......
  • 请注意,any Unicode 编码,包括 UTF-8、16 或 32,除了字节相等之外,不能按字节进行比较。显示可能相同,但使用的字节(例如 R->L 标记、多代码点显示修饰符以及在非英语语言(例如波斯语)中使用的类似内容)将不同。
  • @Yann Ramin:这就是 Unicode 排序算法处理规范化和默认可忽略项的原因。我经常给自己弄一个设置了正确强度级别的整理器对象,然后调用它的相等方法,这样我就不必担心 Unicode 的等不等式或不等式等有趣的想法。
【解决方案2】:

Unicode 是出了名的难以比较。

请注意,任何 Unicode 编码(包括 UTF-8、16 或 32)都不能按字节进行比较,而不是字节相等。显示可能相同,但使用的字节(例如 R->L 标记、代理对、显示修饰符以及在非英语语言(如波斯语)中使用的类似内容)将不同。

一般来说,如果文本的含义有任何意义,你需要对Unicode进行规范化,然后才能进行现实的比较:

http://userguide.icu-project.org/transforms/normalization

【讨论】:

  • Text 是出了名的难以比较。 ASCII 通过忽略世界上 95% 的文本来作弊。
【解决方案3】:

如果您要比较的字符串已经采用特定、明确的编码,则不要使用 wchar_t 也不要使用 L"" 文字——它们不是用于 Unicode,而是用于实现定义的, 不透明编码only.

如果您的字符串采用 UTF-8 格式,请使用 chars 字符串。如果您想将它们转换为原始 Unicode 代码点 (UCS-4/UTF-32),或者如果您已经以这种形式拥有它们,请将它们存储在 uint32_ts 或 char32_ts 的字符串中(如果您有现代编译器。

如果你有 C++11,你的文字可以是 char str8[] = u8"گل";char32_t str32[] = U"گل";See this topic 了解更多信息。

如果您想与命令行参数或环境交互,请使用iconv() 将 WCHAR 转换为 UTF-32 或 UTF-8。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-09
    • 2016-06-10
    • 2011-10-24
    • 1970-01-01
    • 2018-02-01
    • 1970-01-01
    相关资源
    最近更新 更多