如何比较C中的两个字符串忽略新的行字符?

时间:2014-01-31 07:07:17

标签: c

我正在学习C编程,我知道在C strcmp中用来比较两个字符串,但是比较总是包含新行字符,我想忽略它。我知道我可以删除新行字符然后比较它们,但有没有任何函数可以自动忽略新行字符?

3 个答案:

答案 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循环并不是特别优雅。更优雅的答案赞赏。

比较两个字符串的更通用的例程,其中任何一个字符串可以被\nNULL终止(不是你提出的那样):

/* 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'覆盖它)...