通常,有关字符串操作的库函数有strcpy,stract,strcmp,strstr,memcpy和memmove等。本文中将模拟实现这些库函数。
在本文模拟实现的库函数中,统一用char类型指针drr指向源字符串,用char类型指crr指向目标字符串。下面将一一列举:
1.strcpy函数
功能:从drr指向字符串开始且含有’\0’结束符的字符串复制到以crr指向的地址空间。返回值的类型为char*。
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
char * my_strcpy(char *crr, char *drr)
{
assert(crr&&drr);
while (*drr)
{
*crr = *drr;
drr++;
crr++;
}
*crr = *drr;//将'\0'拷进去
return crr;
}
int main()
{
char arr[20] = { 0 };
my_strcpy(arr, "aduoduo");
printf("%s\n", arr);
system("pause");
return 0;
}
2.stract函数
功能:将drr指向的字符串连接到以crr指向的字符串后面,crr和drr所指内存区域不可以重叠,并且crr必须有足够的空间来容纳drr的字符串。返回值的类型为char*。
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
char *my_strcat(char *crr, char *drr)
{
assert(crr&&drr);
//找*crr的‘\0’
while(*crr)
{
crr++;
}
//开始复*drr
while ((*crr++ = *drr++))
{
;
}
return crr;
}
int main()
{
char arr1[20] = "aduo";
char arr2[14] = "duo";
my_strcat(arr1, arr2);
printf("%s\n", arr1);
system("pause");
return 0;
}
3.strcmp函数
功能:比较crr和drr指向的两个字符串。若*crr==drr,则返回零;若crr>*drr,则返回1;否则返回-1。
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
int my_strcmp(char *crr, char *drr)
{
assert(crr&&drr);
while (*crr == *drr)
{
if (*crr == '\0')
{
return 0;
}
crr++;
drr++;
}
if (*crr > *drr)
{
return 1;
}
else
{
return -1;
}
}
int main()
{
char arr1[20] = "aduoduoa";
char arr2[14] = "aduoduob";
int ret=my_strcmp(arr1, arr2);
printf("%d\n", ret);
system("pause");
return 0;
}
4.strstr函数
功能:判断字符串drr指向的两个字符串是否是crr的子串。如果是,则该函数返回drr在crr中首次出现的地址;否则,返回NULL。
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
char * my_strstr( char *crr, char *drr)
{
assert(crr&&drr);
char *cur = crr;
char *s1 = crr;
char *s2 = drr;
//如果drr为空
if (*drr == '\0')
{
return crr;
}
while (*cur)
{
s1 = cur;
s2 = drr;
while (*s1&&*s2&&*s1 == *s2)
{
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return cur;
}
}
//匹配不成功,则cur跳到cur指向字符串下一个元素接着与子字符串比较
cur++;
}
//匹配失败
return 0;
}
int main()
{
char *c = "aduoduoa";
char *d = "duodd";
char * ret = my_strstr(c, d);
if (ret != NULL)
printf("%s\n", ret);
else
printf("找不到\n");
system("pause");
return 0;
}
5.memcpy函数
功能:源drr所指的内存地址的起始位置开始拷贝count个字节到目标crr所指的内存地址的起始位置中。
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
void * my_memcpy(void *crr, void *drr,size_t count)
{
void *ret = crr;
assert(crr&&drr);
while (count--)
{
*(char*)crr = *(char *)drr;
crr = (char*)crr + 1;
drr = (char*)drr + 1;
}
return ret;
}
int main()
{
int arr1[20] = { 0,0,0,0,0 };
int arr2[20] = { 1,2,3,4,5};
my_memcpy(arr1,arr2,20);
system("pause");
return 0;
}
6.memmove函数
源drr所指的内存地址的起始位置开始拷贝count个字节到目标crr。如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,复制后src内容会被更改。
思路:
代码:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
void * my_memove(void *crr, void *drr, size_t count)
{
void *ret = crr;
assert(crr&&drr);
if (crr < drr)//从前向后拷贝
{
while (count--)
{
*(char*)crr = *(char*)drr;
++(char*)crr;
++(char *)drr;
}
}
else
{//从后向前拷贝
while (count--)
{
*((char*)crr + count) = *((char*)drr + count);
}
}
return ret;
}
int main()
{
int arr1[20] = { 1, 2, 3, 4, 5,6,7,8,9, };
my_memove(arr1, arr1+2, 20);
system("pause");
return 0;
}