我正在解决这个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;
}
答案 0 :(得分:4)
快速浏览似乎至少可以揭示一些问题:
答案 1 :(得分:3)
当然,有很多strncmp
和朋友的开源实现(例如,strncmp here),但它们不一定对你有所帮助。
你的strncmp
例如只是实现了错误的算法:它是不的情况是较短的字符串始终“小于”较长的字符串,例如,"z"
是不小于"aa"
- 因此您无法仅通过比较长度来开始。
您的strncpy
正在检查*s
应该检查*t
的位置,以及其他问题。
查看备用开源实现对诊断错误没有多大帮助:对代码进行同行评审,将其发布到SO时可能会有所帮助; - )
答案 2 :(得分:2)
Google代码搜索非常适合查找标准函数的实现:) 例如函数strncpy:
http://www.google.com/codesearch/p?hl=en#XAzRy8oK4zA/libc/string/strncpy.c&q=strncpy&sa=N&cd=1&ct=rc
答案 3 :(得分:0)
有关解决方案,请参阅CLC Wiki page。
现在有一些关于你的代码的评论:
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()
功能。我没有详细研究过这两个,但由于这是一个练习,你可能想要自己做出改变。
答案 4 :(得分:0)
供参考:
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;
}