【问题标题】:Does strcmp(s1,s2) compare only first non equal character value of s1 and s2?strcmp(s1,s2) 是否只比较 s1 和 s2 的第一个不相等的字符值?
【发布时间】:2014-03-15 23:19:30
【问题描述】:

我不相信strcmp()的定义,它说它将比较整个字符串(作为参数传入的两个字符串,并根据s1<s2返回-101s1(同)s2s1>s2

如果是这样,你如何在 K&R 的 sn-p 下证明,在第一次遇到不相等的字符后,你退出循环。我们如何比较 s1s2 的所有字符直到结束 ('\0')?

char *p1 = &str1[0], *p2 = &str2[0];

while (1) {
    if (*p1 != *p2)
        return *p1 - *p2;
    if (*p1 == '\0' || *p2 == '\0')
        return 0;
    p1++;
    p2++;
}

【问题讨论】:

  • 你的描述是从哪里来的?发现差异后,没有必要、没有意义或目的继续比较。
  • @Jongware,我的理解是 str1 = "Aasdasdasd" 大于 str2 = "a",根据 strcmp() 是不正确的,所以我们只是丢弃 Str1 的其他字符?是对的吗?为什么不计算其他字符的 ASCII 值作为最终总和,然后决定谁更大。
  • 因为这不是它的作用.. 如果你想要一个将所有字符 ASCII 值相加的函数,然后创建一个并将其命名为 davids_strtotalsumcmp() 之类的。

标签: c string


【解决方案1】:

strcmp() 将在找到第一个不相等字符后立即停止,因为这足以确定任何两个单词的字典顺序。

这是“经典”strcmp() (1) 的规范

通过仔细计算 known 字符串的 strcmp()unknown 字符串(例如 密码)的结果,人们可能能够确定哪个字符实际上没有通过比较,然后允许使用最多 25*N (或者 255*N,如果您使用整个 ASCII 集,不包括零)尝试来猜测任何字符。这被称为timing attack

所以还有还有secure strcmp() 的实现,它们具有需要与提供的第一个字符串的长度成比例的时间的属性。您可能已经遇到过这样的引用。


(1) 存在其他可能以不同方式处理事物的文本比较函数,例如对于宽字符和多字节字符,有时可能需要两个不同的字符比较相同的字符 - 例如“a”和“à”;但可以说我们不再谈论简单的比较,而是谈论更复杂的collation)。

【讨论】:

  • strcmp 比较字节,而不是宽或多字节字符,因此后者无关紧要。然而,除非你的多字节编码是疯狂的,否则strcmp 也会对多字节字符串做一些合理的事情(例如,使用 UTF-8 它给出了代码点顺序)。
  • 是的,对不起。我指的是更广泛的字符串比较函数。编辑答案。
【解决方案2】:

strcmp 执行两个字符串的经典字典比较。在您找到第一个不匹配字符的那一刻,词典比较的结果就已经立即知道了。这正是您在实施中看到的。

【讨论】:

    【解决方案3】:

    strcmp() 的大多数实现会在两个字符串中的字符不同时立即返回。因此它并不总是比较整个字符串,因为它只对相同的字符串是必要的。

    请注意,如果字符串不同,strcmp() 不一定返回 -11...只有返回值的符号与确定 s1 在字典上是否小于或大于 s2 相关.

    还值得一提的是,char 元素的比较是在它们转换为(unsigned char) 的值上执行的,这使得结果独立于char 符号的编译器设置。 memcmp 也是如此。

    下面是sizeof(char) < sizeof(int) 架构的示例(简单)实现:

    int strcmp(const char *s1, const char *s2) {
        while (*s1 == *s2 && *s1 != '\0') {
            s1++;
            s2++;
        }
        return (unsigned char)*s1 - (unsigned char)*s2;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多