我正在学习C编程,我知道在C strcmp
中用来比较两个字符串,但是比较总是包含新行字符,我想忽略它。我知道我可以删除新行字符然后比较它们,但有没有任何函数可以自动忽略新行字符?
答案 0 :(得分:2)
这是开放代码功能更容易的情况之一。我已经严格测试了相等(即不是字母表),尽管那是一个相对容易的改变。
试试这个,这实际上应该是原始提问者所要求的:
/* Compare two strings s1 and s2, assuming s1 is terminated
* by \n or a NULL, and s2 is terminated by a NULL. A match
* returns 0, a non-match returns 1.
*/
int
strcmpst1nl (const char * s1, const char * s2)
{
char s1c;
do
{
s1c = *s1;
if (s1c == '\n')
s1c = 0;
if (s1c != *s2)
return 1;
s1++;
s2++;
} while (s1c); /* already checked *s2 is equal */
return 0;
}
有趣的是,使用for
循环并不是特别优雅。更优雅的答案赞赏。
比较两个字符串的更通用的例程,其中任何一个字符串可以被\n
或NULL
终止(不是你提出的那样):
/* Compare two strings s1 and s2, assuming either is
* terminated by \n or a NULL, A match
* returns 0, a non-match returns 1.
*/
int
strcmpnl (const char *s1, const char *s2)
{
char s1c;
char s2c;
do
{
s1c = *(s1++);
s2c = *(s2++);
if (s1c == '\n')
s1c = 0;
if (s2c == '\n')
s2c = 0;
if (s1c != s2c)
return 1;
}
while (s1c); /* already checked *s2 is equal */
return 0;
}
另一种效率较低的路线(假设s1由\n
终止)将是:
#include <string.h>
#include <strings.h>
int
strcmpst1nl2 (const char *s1, const char *s2)
{
int s1len, s2len;
s1len = strlen (s1);
s2len = strlen (s2);
/* check strings are equal length without \n */
if (s1len - 1 != s2len)
return 1;
/* we know s1len > 0, as s2len would be -1, so this is safe */
if (s1[s1len - 2] != '\n')
return 1;
return bcmp (s1, s2, s1len - 1);
}
答案 1 :(得分:1)
您应该首先编写一个计算字符串长度的函数,其中标准终止字符和结束字符都终止字符串。在这样做时,我建议您检查换行符和回车符(检查here)
然后,根据先前的定义检查两个字符串是否具有相同的长度。
如果是,则进一步使用strncmp检查字符串(并使用找到的长度作为第三个参数)。
答案 2 :(得分:0)
可以使用类似以下的函数代替strcmp()
。它做了同样的事情,但忽略了第二个字符串上的一个(可能的)尾随换行符。它不会修改字符串。
int my_cmp(const char *str1, const char *str2)
{
int r,n;
/* Get length of str1, which is also the index of the 1st additional
* char in str2
*/
n = strlen(str1);
/* Compare the first n chars */
r = strncmp(str1,str2,n);
/* If 1st n chars match, make sure next char in str2 is either the null char
* or a newline followed by the null char. Otherwise, return -1 since str2 is
* longer (making str1 "less than" str2)
*/
if ( !r && str2[n] && (str2[n] != '\n' || str2[n+1]) )
return -1;
return r;
}
这是另一个忽略任何字符串中任何地址的新行:
int my_cmp(const char *str1, const char *str2)
{
const unsigned char *a, *b;
/* loop over both strings */
for (a = str1, b = str2; ; a++, b++) {
while (*a == '\n') a++; /* skip newlines in str1 */
while (*b == '\n') b++; /* skip newlines in str2 */
/* If we reach the end of either string (or both), one of
* the if's below will terminate the loop */
/* return if we're at end of both strings */
if (!(*a || *b))
return 0;
/* positive return when str1's char is greater than str2's
* (or at end of str2) */
if (*a > *b)
return 1;
/* negative return when str1's char is less than str2's
* (or at end of str1) */
if (*a < *b)
return -1;
}
return 0;
}
当然,如果你只需要忽略一个尾随换行符,那么无论如何都很容易将其剥离(只需找到它并用'\0'
覆盖它)...