字符串函数的模拟实现
- strcpy的模拟实现
我们知道strcpy的功能是将源指向的C字符串复制到目标指向的数组中,包括终止数组
空字符(并在该点停止)。
需要注意的是:
- 源字符串必须以 ‘\0’ 结束
- 会将源字符串中的 ‘\0’ 拷贝到目标空间。
- 目标空间必须足够大,以确保能存放源字符串。
- 目标空间必须可变
仿照库函数strcpy的标准来实现同样功能的一个函数my_strcpy,源字符串中的’\0’会覆盖掉目标字符串剩下的字符串。
代码如下:
char* my_strcpy(char *dest, const char *src)
{
char *ret = dest;
assert(dest != NULL);
assert(src != NULL);
while ((*dest++ = *src++))
{ ; }
return ret;
}
int main()
{
char arr[100] = { 0 };
char brr[] = "world";
char* ret = my_strcpy(arr, brr);
printf("%s\n", ret);
return 0;
}
- strcmp的模拟实现
strcmp的功能为:比较每个字符串的第一个字符。如果它们彼此相等,则继续执行以下对操作,直到字符不同或到达终止的空字符为止。
标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
那么如何比较两个字符串?
逐个比较两个串中对应的字符,字符大小按照ASCII码值确定,从左向右比较,如果遇到不同字符,所遇第一对不同字符的大小关系就确定了两个字符串的大小关系,如果未遇到不同字符而某个字符串首先结束,那么这个字符串是较小的,否则两个字符串相等。
在写这个代码的时候,要注意写while的循环条件*str1==*str2时,用括号括上,以符号在编译时由于编译器分辨不清优先级而结果错误;在打印时注意输出形式的对应,记准%s、%d、%c等c语言的格式输出。
int my_strcmp(const char* str1, const char* str2)
{
assert(str1!=NULL);
assert(str2!=NULL);
while ((*str1 == *str2))
{
if (*str1 == '0')
{
return 0;
}
str1++;
str2++;
}
return *str1 - *str2;
}
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abcq";
printf("%d\n", my_strcmp(arr1,arr2));
return 0;
}
- strstr的模拟实现
strstr的功能为:返回指向str1中第一次出现的str2的指针,如果str2不是str1的一部分,则返回空指针。
在写这个函数时要考虑多种情况,不能只考虑简单的情况,比如,arr1[]=“abbbcde”,arr2[]="bbc"这种稍微复杂一点的情况,设置三个指针分别指向str1,str2,cur负责记录s1与s2比较的起始位置。
当s1不等于s2时,s1向后走,同时,cur也向后移动一个位置。
此时,s1=s2,s1继续向后走,s2同样继续向后走,此时s1=b=s2=b,重复上述过程,s1继续往后走,s2也继续往后走,此时,s1=b,s2=c,s1与s2不再匹配
此时,cur向后走,s1返回cur的位置,s2返回最开始的位置,s1与s2重新比较,
重复上述过程,s1向后走,s2向后走,当s1=s2=c时,s2已访问完,此时,已在s1中找到与s2完全相同的字符串,这时应返回cur的的位置,并打印该字符串。
此外,也可能遇见s2还没访问完,s1已经结束,比如,arr1[]=“abcdef”,arr2[]=“defg”,此时,str1中并未找到与str2相符的字符串,故应返回空指针。
具体代码如下:
char *my_strstr(char *str1, const char *str2)
{
char* s1 = str1;
char* s2 = str2;
char* cur = str1;
while (*cur)
{
s1 = cur;
s2 = str2;
while (*s1 && *s2 && (*s1 == *s2))
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return cur;
}
/*if (*s1 == '0')
{
return NULL;
}*/
cur++;
}
return NULL;
}
int main()
{
char arr[] = "abcdef";
char brr[] = "bc";
char *ret = my_strstr(arr, brr);
printf("%s\n", ret);
return 0;
}
4.strcat
char *my_strcat(char *dest, const char *src)
{
char *ret = dest;
assert(dest != NULL);
assert(src != NULL);
while (*dest)
{
dest++;
}
while ((*dest++ = *src++))
{
;
}
return ret;
}
int main()
{
char arr1[] = {0};
char arr2[] = "world";
char *ret = my_strcat(arr1, arr2);
printf("%s\n", ret);
return 0;
}
5.strchr的模拟实现
strchr的功能:找出某个字符在字符串中第一次出现的地址,相对于strstr比较简单,具体代码如下:
char *MyStrchr(const char *dest, const char c)
{
assert(dest);
while (*dest)
{
if (*dest == c)
{
return dest;
}
dest++;
}
return NULL;
}
int main()
{
char arr1[] = "abcdef";
char *ret = strchr(arr1,'d' );
printf("%s\n", ret);
}
6.memcpy的模拟实现
函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
这个函数在遇到 ‘\0’ 的时候并不会停下来。
如果source和destination有任何的重叠,复制的结果都是未定义的
具体代码如下:
void * memcpy(void * dst, const void * src, size_t count)
{
void * ret = dst;
/* copy from lower addresses to higher addresses*/
while (count--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
return (ret);
}
int main()
{
char arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, };
char arr2[] = { 1, 2 };
my_memcpy(arr1, arr2, strlen(arr1));
printf("%s", arr1);
return 0;
}