繁体   English   中英

如何编写C字符串函数:strncpy,strncat和strncmp

[英]How to write C string functions: strncpy , strncat , and strncmp

我正在解决这个K&R练习:

编写库函数strncpy,strncat和strncmp的版本,这些函数最多只能运行其参数字符串的前n个字符。 例如,strncpy(s,t,n)最多复制t到s的n个字符。 完整说明见附录B.

所以,如果有一个网站包含这些字符串函数的源代码,我就会徘徊,所以我可以查看是否我做错了什么。

这些是我写的版本:如果你告诉我,如果我在函数中有一些错误或我应该添加/纠正/改进的东西,我将不胜感激!

int strncmp(char *s, char *t, int n)
{

     if(strlen(s) == strlen(t)) {

         while(*s == *t && *s && n) 
            n--, s++, t++;

         if(!n) 
             return 0; /* same length and same characters */
         else 
             return 1; /* same length, doesnt has the same characters */         
     }
     else
        return strlen(s) - strlen(t);
}

char *strncpy(char *s, char *t, int n)
{
     while(n-- && *s) {
        *s = *t;
        s++, t++;
     }

     if(strlen(t) < n)
        *s = '\0';

     return s;
}

char *strncat2(char *s, char *t, int n)
{
     while(*s)
       s++;

     while(n-- && *t) 
       *s = *t, s++, t++;

     *s = '\0';
     return s;
}

快速浏览似乎至少揭示了几个问题:

  • 在strncmp中:对输入的strlen()调用无效。 它们不必被空终止。 此外,返回值应为<0,= 0,> 0,具体取决于相等性。
  • strncpy:我相信库版本用\\ 0填充字符串到末尾。

当然,也有大量的开放源代码实现的strncmp和朋友(例如,STRNCMP 这里 ),但他们不一定会帮你这么多。

例如,你的strncmp只是实现了错误的算法: 不是这样的情况,一个较短的字符串总是“小于”一个较长的字符串,例如, "z" 小于"aa" - 所以你不能通过比较开始只有长度。

你的strncpy正在检查*s应该检查*t ,以及其他问题。

查看备用开源实现对诊断您的错误没有多大帮助:对您的代码进行同行评审,就像通过将其发布到SO一样,可能有助于更多;-)

Google代码搜索非常适合查找标准函数的实现:)例如strncpy:

http://www.google.com/codesearch/p?hl=en#XAzRy8oK4zA/libc/string/strncpy.c&q=strncpy&sa=N&cd=1&ct=rc

有关解决方案,请参阅CLC Wiki页面

现在一些关于你的代码的评论:

对于strncmp

if(strlen(s) == strlen(t)) {

你不需要这个检查。 strlen()遍历字符串,因此如果长度相等,您将处理字符串两次。 这可能会变得昂贵。 一般来说,像这样的低级函数,在任何程序中都可以被大量调用,应该是有效的(尽管过早的优化是万恶之源!)。 此外,如果长度不相等,则再次为两个字符串调用strlen() 除了昂贵之外,它也是错误的,但我们稍后会谈到这一点。 关于你的while循环:

while(*s == *t && *s && n) 
    n--, s++, t++;

为什么要滥用逗号运算符? 我会简化并编写上面的内容(未经测试,毕竟,这是正在解决的练习!):

while (*s && *t && *s == *t && n--) {
    s++;
    t++;
}
if (!n) return 0;
else return *s - *t;

您的返回值是错误的。 strncmp()应返回0,小于0或大于0,具体取决于第一个字符串的前n字符是否等于,小于或大于(按字典顺序)第二个字符串。

同样,您应该更改strncpy()strncat2()函数。 我没有详细看过这两个,但由于这是一个练习,你可能想要自己做出改变。

以供参考:

char* strncpy(char* s, const char* t, size_t n)
{
    char* ret = s; // need to return this
    while (n-- && *s++ = *t++)
         ;
    if (n) *s = 0;
    return ret;
}

// be lazy, there's no reason to write the copy part of strncpy and strncat twice.
char* strncat(char* s, const char* t, size_t n)
{
     char *ret = s;
     strncpy(s+strlen(s), t, n);
//
//   // if you don't want to call strlen, you can do this
//   while (*s++) ;
//   strncpy(s, t, n);
//
     return ret;
}

int strncmp(const char* s, const char* t, size_t n)
{
    while (n-- && *s == *t) {
          ++s;
          ++t;
    }
    if (n) return *s - *t;
    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM