首先我们来看看MSDN库里函数的大概模型 strcpy函数的功能就是字符串拷贝, 我们可以用指针移动赋值来实现 一直到‘\0’停止 根据函数功能我们可以写出如下代码
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<assert.h> char *my_strcpy(char *dest, const char *src) { char *cp = dest; assert(dest!=NULL);//断言,dest如果为空程序会崩溃 while (*dest++ = *src++)//这样写在退出循环的同时,把‘\0’也赋给*dest了 { NULL;//空语句这样写,更加容易让人看 } return cp; } int main() { char str[5] = ""; char *p = my_strcpy(str,"abcd"); printf("%s", p); system("pause"); return 0; }下来我们来看看库里函数的源代码,发现和我们写的几乎没有什么区别
strcpy: 1./* 2. * strcpy - Copy a %NUL terminated string 3. * @dest: Where to copy the string to 4. * @src: Where to copy the string from 5. */ 6.char *strcpy(char *dest, const char *src) 7.{ 8. char *tmp = dest; 9. 10. while ((*dest++ = *src++) != '\0'); 11. 12. return tmp; 13.}观察源代码你会发现,strcpy函数没有判断是否越界的步骤,所以在用这个函数时 要注意字符串长度和目标字符串空间大小。
因为字符串拷贝函数strcpy安全性不好,所以就有了strncpy 它是干什么的哪? 函数字符串拷贝,只不过比strcpy多了一个参数就是拷贝个数 这样我们就用把判断条件稍加修改就可以了 先看看MSDN中
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<assert.h> char *my_strncpy(char *dest, const char *src,int count)//const 可以让代码具有更好的健壮性 { char *cp = dest; assert(dest!=NULL); while (count--&&(*dest++=*src++)) { NULL; } if (count != 0) { *dest = '\0'; } return cp; } int main() { char str[5] = ""; //char *p = my_strncpy(str,"abcd",2); char *p = my_strncpy(str, "abcd", 2); printf("%s\n", p); system("pause"); return 0; }下面我们来看看库里的源代码
char * __cdecl strncpy ( char * dest, const char * source, size_t count ) { char *start = dest; while (count && (*dest++ = *source++)) /* copy string */ count--; if (count) /* pad out with zeroes */ while (--count) *dest++ = '\0'; return(start); }本质上没有什么区别
字符串追加函数 因为是追加函数所以要先找到目标字符串的‘\0’,然后在指针偏移进行赋值就可以了
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<assert.h> char *my_strcat(char *dest, const char *src) { char *tem = dest; assert(dest != NULL&&src != NULL); while (*dest) { dest++; } while (*dest++ = *src++) { NULL; } return tem; } int main() { char str[10] = "abcd"; char *p = my_strcat(str, "abcd"); printf("%s\n", p); system("pause"); return 0; }strcat源代码:
char * __cdecl strcat ( char * dst, const char * src ) { char * cp = dst; while( *cp ) cp++; /* find end of dst */ while( *cp++ = *src++ ) ; /* Copy src to end of dst */ return( dst ); /* return dst */ }MSDN中: 和strcat差不多,只是在strcat的基础上再加一个追加个数的限定条件
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<assert.h> char *my_strncat(char *dest, const char *src,int count) { char *tem = dest; assert(dest != NULL&&src != NULL); while (*dest) { dest++; } while (count--&&(*dest++ = *src++)) { NULL; } return tem; } int main() { char str[10] = "abcd"; char *p = my_strncat(str, "abcd",1); printf("%s\n", p); system("pause"); return 0; }下面是库函数源代码:
char * __cdecl strncat ( char * front, const char * back, size_t count ) { char *start = front; while (*front++) ; front--; while (count--) if (!(*front++ = *back++)) return(start); *front = '\0'; return(start); }MSDN: 还是用指针移动来实现,指针移动直到遇到‘\0’为止,再来一个简单的计数器就可以求出字符串长度。
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<assert.h> int my_strlen(const char *str) { int count = 0; assert(str != NULL); while (*str++) { count++; } return count; } int main() { char *str = NULL; int t = my_strlen(str); printf("%d\n", t); system("pause"); return 0; }strlen库函数源代码:
size_t __cdecl strlen ( const char * str ) { const char *eos = str; while( *eos++ ) ; return( eos - str - 1 ); }可以看到strlen返回的是一个siez_t类型的值,这个类型实在头文件stddef.h中定义的,是一个无符号整数类型所以 if( ( strlen( x ) - strlen( y ) ) >=0)这样的表达式是不对的,因为strlen返回的是无符号类型值,所以>=左边是一个无符号类型的值,而无符号的值不可能为负的,所以这里条件恒成立。 这里可以看到库函数中没有用计数器来一个 一个加,而是直接用指向‘\0’地址减去指向首元素的地址再减去1 在C中只能相同类型指针指向的地址能进行减法运算,算出来的是中间相隔的元素个数+1