Strncmp 实现

use*_*325 2 c string compare

我有以下带有测试驱动程序的 strncmp 函数实现,但是无法编译。

我也不确定逻辑是否正确。这是来自我的编译器的错误消息:

警告:控件可能会到达非空函数的结尾 [-Wreturn-type]

#include <stdio.h>
#include <string.h>

#undef strncmp

int strncmp(const char *s, const char *t, size_t num)
{
    for ( ; num >0;  s++, t++, num--)
        if (*s == 0)
            return 0;

    if (*s == *t) {
        ++s;
        ++t;
    }
    else if (*s != *t)
        return *s - *t;  
}

 int main ()
 {
   char str[][5] = { "R2D2" , "C3PO" , "R2A6" };
   int n;
   puts ("Looking for R2 astromech droids...");
   for (n=0 ; n<3 ; n++)
     if (strncmp (str[n],"R2xx",2) == 0)
     {
       printf ("found %s\n",str[n]);
     }
   return 0;
 }
Run Code Online (Sandbox Code Playgroud)

Dev*_*lar 5

除了其他人提到的错误之外,您应该将字符比较为unsigned char. 一旦您超越 ASCII-7,这一点就变得很重要,否则您的结果将是错误的

以下是我自己的(经过测试的)实现(来自我对PDCLib 的原始工作,这是CC0 许可的)。

int strncmp( const char * s1, const char * s2, size_t n )
{
    while ( n && *s1 && ( *s1 == *s2 ) )
    {
        ++s1;
        ++s2;
        --n;
    }
    if ( n == 0 )
    {
        return 0;
    }
    else
    {
        return ( *(unsigned char *)s1 - *(unsigned char *)s2 );
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 考虑`char s1[4] = {1,2,3,4}; strncmp(s1, s2, sizeof s1)`。原始答案访问了超出 s1[] 和 UB 的 s1[4] 。最初传递的 `s1` 可以使 `*s1` 表现良好,但是增加 _and_ 访问它一次太远是我的评论所关注的问题。 (2认同)