strcpy的使用和模拟实现
strcpy的使用
strcpy,拆开是string copy,即字符串拷贝,作用是将字符串从一个位置拷贝到另一个位置,它的函数原型如下:
char* strcpy(char * destination, const char * source );
其中destination是指向目标字符串的指针,source是指向源头字符串的指针。
它需要一个源头字符串和目标字符串,它会将源头字符串复制到目标字符串中。
我们来使用一下:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[20] = { '0' };
char arr2[] = "abcdef";
strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
结果为:

那么arr2字符串末尾的\0有没有被复制过去呢?我们来测试一下:

调试可知\0确实被拷贝过去了。
注意事项
- 1 .源头字符串要不可修改,目标字符串要可修改。
-
- 源头字符串要以\0结尾
- 3.目标字符串要有足够大的空间以存放源头字符串,例如
char arr1[20]就留出了20个元素的空间。
strcpy的模拟实现
我们需要两个指针dest和src,分别指向arr1和arr2,*src赋值给*dest后,两个指针同时向后移动一个单位,再次进行赋值操作,直到*src == ‘\0’。再单独将\0赋值给arr1

代码:
#include <stdio.h>
#include <string.h>
char* my_strcpy(char* dest, char* src)
{
char* ret = dest;
while (*src != '\0')
{
*dest = *src;
dest++;
src++;
}
if (*src == '\0')
{
*dest = *src;
}
return ret;
}
int main()
{
char arr1[20] = "xxxxxxxxxxxxxxxxxxxx";
char arr2[] = "abcdef";
my_strcpy(arr1, arr2);
return 0;
}
当然我们可以优化一下:
arr2不能被修改,我们就在src前加一个const修饰。
为了防止dest和src是野指针,我们可以加一个assert断言。
我们也可以把‘\0’的赋值融到上一段代码中。
优化后为:
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strcpy(char* dest, const char* src)
{
assert(dest != NULL && src != NULL);
char* ret = dest;
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[20] = "xxxxxxxxxxxxxxxxxxxx";
char arr2[] = "abcdef";
printf("%s\n", my_strcpy(arr1, arr2));
return 0;
}
下面的代码实现了既能打印正常字符又能打印’\0’,因为后置++是先使用,再加1,*src先赋值给*dest,然后src再加1,直到*src = '\0'赋值给*dest后,while停止循环。
while (*dest++ = *src++)
{
;
}
strcat的使用和模拟实现
strcat的使用
strcat实现的是字符串追加,即将源头字符串加在目标字符串的后边。
strcat的函数原型如下:
char* strcat(char* dest,const char* src)
我们来使用一下:
#include <stdio.h>
#include <string.h>
#include <assert.h>
int main()
{
char arr1[20] = "abc";
char arr2[] = "def";
strcat(arr1,arr2);
printf("%s\n", arr1);
return 0;
}
结果:

可见"def"成功加在了"abc"的后面。
源头字符串的’\0’也加在了后面,可以自己调试验证一下。
注意事项
- 1.源头字符串必须以’\0’结束
- 2.目标空间要足够大
- 3.目标字符串要可修改
strcat的模拟实现
为了实现追加,我们要让src指针移动到源头字符串‘\0’的位置,然后在进行逐个拷贝的操作,当然我们要记录一下dest的起点ret

代码为:
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strcat(char* dest, const char* src)
{
assert(dest && src);
char* ret = dest;
while (*dest)
{
dest++;
}
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[20] = "abcd";
char arr2[] = "efg";
printf("%s\n", my_strcat(arr1, arr2));
return 0;
}
那么问题来了,我们可不可以给字符串自身追加它自身呢?我们来分析一下:
dest遇到\0后开始拷贝,\0被修改为a,当src遇到原\0的位置时,遇到的实际上是a,造成src无法停止并循环拷贝,结果为abcabcabcabc…

strcmp的使用和模拟实现
strcmp的使用
strcmp 函数是 C 语言中用于比较两个字符串的函数,其声明如下:
• 函数原型:
int strcmp(const char *str1, const char *str2);
• 参数:
• str1: 要比较的第一个字符串。
• str2: 要比较的第二个字符串。
• 返回值:
• 如果返回值小于 0,表示 str1 小于 str2。
• 如果返回值大于 0,表示 str1 大于 str2。
• 如果返回值等于 0,表示两个字符串相等
那么如何判断两个字符串?⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩。
strcmp的模拟实现
int my_strcmp (const char * str1, const char * str2)
{
int ret = 0 ;
assert(str1 != NULL);
assert(str2 != NULL);
while(*str1 == *str2)
{
if(*str1 == '\0')
return 0;
str1++;
str2++;
}
return *str1-*str2
strstr的使用和模拟实现
strstr的使用
strstr,即string string,作用是在字符串中查找特定字符串,例如在“abcdefg”中找出“cde”.它的函数原型如下:
char *strstr(const char *str1, const char *str2)
函数会返回字符串str2在字符串str1中第⼀次出现的位置。
我们使用一下:
#include <stdio.h>
#include <string.h>
#include <assert.h>
int main()
{
char arr1[] = "abcdefgh";
char arr2[] = "def";
char* p = strstr(arr1, arr2);
printf("%s\n", p);
return 0;
}
结果:

strstr的模拟实现
我们需要将*str1与*str2进行逐个比较,判断*str1和*str2是否相等,当str2找到\0的时候结束并返回str1与str2开始相等的位置。

但我们还需要str1,str2的初始位置以便于发现不相等之后重新判断,所以我们要再引用两个指针s1,s2进行移动,而str1和str2的位置固定不变。

然后我们还需要一个指针cur用来记录开始匹配成功的位置。

char* my_strstr(char* str1, char* str2)
{
char* s1 = str1;
char* cur = str1;
while (*s1)
{
char* s2 = str2;
if (*s1 == *s2)
{
cur = s1;
while (*s1 == *s2&&*s2 != '\0')
{
s1++;
s2++;
}
}
if (*s2 == '\0')
{
return cur;
}
s1++;
}
return NULL;
}
但当这种情况时,s1,s2匹配失败后又需要s1回到cur的位置并+1移动到下一个位置继续匹配,所以我们再添一段代码:

char* my_strstr(char* str1, char* str2)
{
char* s1 = str1;
char* cur = str1;
while (*s1)
{
char* s2 = str2;
if (*s1 == *s2)
{
cur = s1;
while (*s1 == *s2&&*s2 != '\0')
{
s1++;
s2++;
}
}
if (*s2 == '\0')
{
return cur;
}
if (*cur == *(cur + 1))
{
s1 = cur;
}
s1++;
}
return NULL;
}
int main()
{
char arr1[] = "abcdefgbcqffff";
char arr2[] = "bcq";
char* p = my_strstr(arr1, arr2);
if (p == NULL)
{
printf("找不到");
}
printf("%s\n", p);
return 0;
}
最后再考虑一下特殊情况就完成了:
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strstr(char* str1, char* str2)
{
assert(str1 && str2);
if (*str2 == '\0' || *str1 == '\0')
{
return NULL;
}
char* s1 = str1;
char* cur = str1;
while (*s1)
{
char* s2 = str2;
if (*s1 == *s2)
{
cur = s1;
while (*s1 == *s2&&*s2 != '\0')
{
s1++;
s2++;
}
}
if (*s2 == '\0')
{
return cur;
}
if (*cur == *(cur + 1))
{
s1 = cur;
}
s1++;
}
return NULL;
}
int main()
{
char arr1[] = "abcdefgbcqffff";
char arr2[] = "bcq";
char* p = my_strstr(arr1, arr2);
if (p == NULL)
{
printf("找不到");
}
printf("%s\n", p);
return 0;
}

被折叠的 条评论
为什么被折叠?



