如果一个有 '\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);
}
假设两个字符串在 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);
}