str函数的模拟(包括strn函数的模拟)
首先先说这些函数引用的头文件是<string.h>
1.strlen函数
int my_strlen(char* s1) {
//这里只用最难的方法
if (*s1) {
return my_strlen(s1 + 1) + 1;
}
else
return 0;
}
这里使用了递归的方法(不创建新的变量),如果需要看指针,数组用计数器count(创建新变量)的方法看之前发的文章string函数的模拟即可;
讲解一下这个函数的作用:这个函数能求解'\0'之前元素个数,直到找到'\0',如果找不到就会生成随机数。
注意点:这些str函数返回值一般都是unsigned int 类型,但是我的模拟函数都是返回int型,如果用库函数的话,做减法要注意不会出现负值。
2.strcpy函数
void my_strcpy(char* s1, const char* s2) {
assert(s1 && s2);
while (*s1++ = *s2++)//这里可以刚好把’\0‘给拷贝过去然后出来
;
}
该函数的功能就是将一个字符串的内容进行拷贝到另一个字符串,为啥不直接使用赋值呢?
char str[20]="abcd";
str="abcd";这样是错误的,因为现在的str代表的是字符串首元素的地址,是没办法直接进行赋值的;
注意:要看好传入的是啥,前面的是要拷贝的位置,后面那个是要拷贝内容的地址;
3.strcat函数
void my_strcat(char* s1, const char* s2) {
assert(s1 && s2);
while (*s1++)
;
s1--;
while (*s1++ = *s2++)
;
}
该函数的作用是将一段字符串加在另外一段字符串的后面;
4.strstr函数
char* my_strstr(const char* s1, const char* s2) {
while (*s1) {
char* p = s1;
char* new_s2 = s2;
while (*p == *new_s2 && *new_s2 != '\0' && *p != '\0') {
p++;
new_s2++;
}
if (*new_s2 == '\0') {
return s1;
}
s1++;
}
return NULL;
}
这个函数的作用是判断是否为字串后,返回开始符合字串到结尾所在的所有剩余字符;
6.strtok函数
#define _CRT_SECURE_NO_WARNINGS 1//不加上会报错
int main() {
char str1[] = "www.baidu@com";
char* str = "@.";
char* ret = NULL;
char str2[20] = {0};
strcpy(str2, str1);
ret = strtok(str2, str);
printf("%s\n", ret);
ret = strtok(NULL, str);
printf("%s\n", ret);
ret = strtok(NULL, str);
printf("%s\n", ret);
ret = strtok(NULL, str);
printf("%s\n", ret);
return 0;
}
strtok有两种机制:
1.如果strtok不为NULL,那么会保存@的位置(@会被改成\0)
2.如果strtok为 NULL,那么会从上次strtok所保存@的位置,继续往下找seq中的字符,如果找到,接着分割。最后再保存被改成\0的位置。
最后:如果strtok找到了没被改的\0,也就是字符串末尾的\0时,返回NULL。
7.strncpy函数
char* my_strncpy(char* s1, const char* s2,int count) {
assert(s1&& s2);
char* s1_new = s1;
while (count && (*s1_new++ = *s2++) != '\0') {
count--;
}
if (count) {
while (--count) {//这里先减减是因为上面在离开循环的时候已经处理过一次了,但是没有count--;这样处理之后循环能少一次
*s1_new++ = '\0';
}
}
return s1;
}
这个函数可以确定控制要拷贝的个数,如果供给拷贝的字符串短于要拷贝的个数,剩余的使用'\0'进行补充。
8.strncat函数
char* my_strncat(char* s1, const char* s2, int count) {
assert(s1 && s2);
char* start = s1;
while (*s1++)
;
s1--;
while (count--) {
if ((*s1++ = *s2++) == '\0')
return (start);
}
*s1 = '\0';
return (start);
}
这个的逻辑是加到出现'\0'就直接return离开,如果还没有出现'\0'最后给截止的'\0'再离开,返回的是一个字符串首元素的地址。