[英]questions regarding string functions like strcat(), strncpy(),strncat()?
[英]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
和朋友(例如,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.