如果一个有 '\n' 而另一个没有,C 会匹配两个字符串吗?

Will C match two strings if one has a '\n' but the other doesn't?

假设两个字符串在 C 中是否完全相同,只是其中一个在空终止符之前的末尾有一个 '\n'。如果我们尝试使用 strcmp 来查看两个字符串是否相同,strcmp 会将它们匹配为相同还是不同?

如果不匹配,我们如何解决这个问题并忽略'\n'?

不,它不会,strcmp() 只匹配完全相等的值,事实上,strcmp() 执行一个操作,它可能 return 一个正值或负值,具体取决于两者之间的差异两个字符串,它 returns 0 当它们完全相等时,即

假设你 strcmp(A, B) == 0 那么字符串 A 中的每个字符都等于字符串 B[= 中的每个字符并且与它们处于完全相同的位置20=].

strcmp 检查确切的身份。 '[=12=]' 以外的任何字符都是字符串的一部分。

一个简单的解决方案当然是用[=14=]覆盖\n,然后调用strcmp。但是,如果此时不允许您修改字符串, 这是一种方法,它保留了 strcmp 的字典顺序:

size_t len1 = strlen(str1);
size_t len2 = strlen(str2);

if ( len1 == len2 + 1 && str1[len1 - 1] == '\n' && 0 == memcmp(str1, str2, len1) )
    return 0;

if ( len2 == len1 + 1 && str2[len2 - 1] == '\n' && 0 == memcmp(str1, str2, len2) )
    return 0;

return strcmp(str1, str2);

他们不匹配。 有很多情况,一个或多个 \n 在字符串的开头或结尾。 最灵活的方法是在比较之前 trim (剥离)两个字符串。参见 this answer

对于简单的情况,以下可能有效。基于 strcmp 实现。它允许多个 \n 最后 并且可以很容易地修改为 trim 其他字符,如 \r\t 尽管它失败了在 strcmp_lf("1234\n", "1234\n\n1234")

这样的情况下
 static int is_strend(const char a){
     if (a == '[=10=]') return 1;
     if (a == '\n') return 1;
     //if (a == '\t') return 1;
     //if (a == '\r') return 1;
     return 0;
 }

 int strcmp_lf(const char *s1, const char *s2)
 {
     for ( ; *s1 == *s2 || (is_strend(*s1) && is_strend(*s2)); s1++, s2++)
     if (*s1 == '[=10=]' || *s2 == '[=10=]')
         return 0;
     return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1);
 }