【问题标题】:Can i use memcmp two compare multibyte characters string?我可以使用 memcmp 两个比较多字节字符串吗?
【发布时间】:2012-03-16 16:15:49
【问题描述】:

我正在尝试编写代码来比较两个字符串。 在 Windows 中我可以使用 strcmp 但我想写多字节字符串,以便它与所有其他平台兼容 我可以使用 memcmp 吗? 如果没有,那么我可以使用任何其他 API,或者我需要编写自己的 API。

【问题讨论】:

  • 这取决于两个字符串是否使用相同的编码。

标签: c++ string multibyte memcmp


【解决方案1】:

你必须小心。我不是 Unicode/多字节编码方面的专家,但我知道使用变音符号有时可以认为两个字符串在它们的字节不完全相同时相等。建议使用预先测试过的 API,因为字符串编码会变得非常混乱。

the old new thing on case mapping。我想不出关于变音符号的参考,但如果我想到了,我会发布它。

【讨论】:

  • 这是正确的。在某些情况下,memcmp 会起作用。为了 100% 的正确性,特别是如果涉及任何形式的 Unicode,memcmp 将不起作用。即使是像é 这样的简单字符也可以用不止一种方式表示——要么是é(一个Unicode 字符),要么是´ 结合e(两个Unicode 字符)。大多数情况下,这些不会混合和匹配,所以你可能一开始看不到任何问题,但最终它会咬你。
  • 字符串可以被“认为”相等但不是字节相等的另一种方式是,如果您的比较是不区分大小写的。在这种情况下,您需要执行所谓的大小写折叠,它允许比较大写、小写、标题大小写和大小写不变的字形(如上所述,它可以在内存中表示为多个代码点......或不)。
  • 归一化后相等与相等不是一回事。这就是标准化的全部意义所在。 OP 是在询问两个字符串字符串是否相等,而不是它们是否相等。
  • @Bingo:案件处理更糟糕。在土耳其语中,i 的大写字母不是I,而是İI 上面有一个点),I 的小写字母不是i,而是ı(无点) i),在这种情况下,您需要知道书写单词的语言。 :)
  • 这里是关于各种 Unicode 规范化类型(字符可以编码的各种方式)的参考。 unicode.org/reports/tr15/#Introduction 请注意,UTF8 特别需要字符的最短编码,但这是 UTF8、AFAIK 特有的——其他类型的 Unicode 更为宽松。
【解决方案2】:

如果两个字符串使用相同的编码,您可以使用memcmp。如果他们使用 UTF-8 并且您的字符串不包含 NULL 字符 (U+0000),您甚至可以使用 strcmp,因为在没有 NULL 本身的情况下,UTF-8 编码字符串中不会出现 0 .另一种选择是使用mbstowcs 将字符串转换为宽字符。

【讨论】:

  • 这会有误报——两个相同的字符串可以被编码成不同的字节模式。您需要与一个精通 Unicode 的函数进行比较。
  • @StilesCrisis - 您能否提供一个示例,说明相同的字符串如何具有不同的 UTF-8 编码?或者,就此而言,任何其他信号编码(如 ISO 8859-1)怎么会发生这种情况?我确实指出字符串需要使用相同的编码。
  • @Ted Hopp:使用 UTF-8,您可以将字符编码为超长形式(解码为应使用较短序列的值的序列:这句话来自维基百科)。在这种情况下,memcmp 返回错误答案,但 UTF-8 感知比较函数返回正确答案...
  • @Malkocoglu - 从 Unicode 版本 3.0 开始,该标准禁止生成非最短格式的 UTF-8 序列。 (这是标准中的符合性条款 C12。)以超长形式编码的字符串未使用合法的 UTF-8 编码。 (同一维基百科页面在Invalid byte sequences 部分下列出了“超长形式”。)
  • @Ted Hopp :如果您对格式不正确的 UTF8 字符串使用 memcmp/strcmp,它们将返回 OK,就好像它们是有效序列一样。如果您使用 UTF8 感知比较函数,则如果其中一个字符串格式错误,它将/必须返回错误。这是我的观点,我也反对格式错误的 UTF8...
【解决方案3】:

如果两个字符串都使用相同的编码,memcmp 可以正常工作。但是请记住,宽字符在不同平台上的大小不同。

如果字符串使用不同的编码,则需要ICU之类的库来处理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 2012-08-07
    • 2013-11-15
    • 2018-11-29
    相关资源
    最近更新 更多