当我们在学习字符串的时候,经常会使用到strlen、strcpy、strcat、strstr、strcmp这几个库函数,但今天我们就用代码来自己实现my_strlen、my_strcpy、my_strcat、my_strstr、my_strcmp这几个函数。
strlen
功能:计算字符串长度(不计算’\0’)
返回值类型:int
实现my_strlen有三种方式:
1.计数法
思路:顾名思义,就是从前往后一个一个数
int my_strlen(const char *str)
{
int count = 0;
assert(str);//断言str有效
while (*str++)
{
count++;
}
return count;
}
int main()
{
char arr[100] = "abcdef";
int ret = my_strlen(arr);
printf("%d\n", ret);
system("pause");
return 0;
}
2.递归
这种方法不用创建临时变量
int my_strlen(const char *str)
{
assert(str);
if (*str == '\0')
return 0;
else
return 1 + my_strlen(++str);
}
3.指针相减
思路:一个指针指向首地址,另一个指针指向’\0’
int my_strlen(char *str)
{
char *ret = str;
assert(str);
while (*ret != '\0')
{
ret++;
}
return ret - str;
}
结果:6
strcpy
功能:strcpy( char *dest, const char *str ) 将str所指字符串拷贝到dest所指的字符串中,并且dest和str所指的内存不能重 叠,这就要求dest要有足够的空间来存储str所指的内容。
返回值类型:char* (为了实现链式访问)
思路:将str所指内容按顺序逐一拷贝到dest所指的字符串中
char* my_strcpy(char *dest, const char *str)
{
char *ret = dest;
assert(dest && str);
while (*dest++ = *str++)
{
;
}
return ret;
}
int main()
{
char arr1[100] = { 0 };
char arr2[] = "abcdef";
char *ret = my_strcpy(arr1, arr2);
printf("%s\n", ret);
system("pause");
return 0;
}
结果:abcdef
strcat
功能:strcpy( char *dest, const char *str ) 将str所指向的字符串复制到dest所指向的字符串的后面(覆盖掉原来dest所指向字符串的’\0’)
返回值类型:char*
思路:先找到dest所指向字符串的’\0’,然后开始复制str所指向字符串的内容(注:要将str所指向字符串的’\0’页复制)
char* my_strcpy(char *dest, char *str)
{
char *ret = dest;
assert(dest && str);
while (*dest)
{
dest++;
}
while (*dest++ = *str++)
{
;
}
return ret;
}
int main()
{
char arr1[100] = "abcdef";
char arr2[100] = "ghijk";
char *ret = my_strcpy(arr1, arr2);
printf("%s\n", ret);
system("pause");
return 0;
}
结果:abcdefghijk
strstr
功能:strstr( const char *str1, const char *str2 ) 查找str2所指向的字符串是否是str1所指向字符串的子串,则返回str2在str1的首次出现的地址,若不是,则返回NULL
返回值类型:char *
思路:对str1所指向的字符串进行遍历,看是否包含str2所指向的字符串
char* my_strstr(char *str1, char *str2)
{
assert(str1 && str2);
char *start = str1;
char *cur = str2;
char *s1 = NULL;
if (*str2 == '\0')
{
return NULL;
}
else
{
while (*start)
{
s1 = start;
cur = str2;
while (*s1 && *cur && (*s1 == *cur))
{
s1++;
cur++;
}
if (*cur == '\0')
{
return start;
}
start++;
}
}
}
int main()
{
char arr1[] = "abbcdefg";
char arr2[] = "bcd";
char *ret = my_strstr(arr1, arr2);
if (*ret)
{
printf("%s\n", ret);
}
else
{
printf("找不到\n");
}
system("pause");
return 0;
}
结果:bcdefg
strcmp
功能:strcmp( const char *str1, const char *str2 ) 比较两个字符串的大小
返回值类型:int 若为0,两个字符串相等;若为1,第一个字符串大;若为-1,第一个字符串小
思想:将两个字符串对应位置进行相减(第一个减去第二个)
int my_atrcmp(const char str1[], const char str2[])
{
assert(str1 && str2);
int ret = 0;
while ( !(ret = *(unsigned char *)str1 - *(unsigned char *)str2) && *str1 )
{
str1++;
str2++;
}
if (ret < 0)
return -1;
else if (ret > 0)
return 1;
else
return 0;
}
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abcdef";
int ret = my_atrcmp(arr1, arr2);
if (0 == ret)
{
printf("相等\n");
}
else if (-1 == ret)
{
printf("第一个小\n");
}
else
{
printf("第一个大\n");
}
system("pause");
return 0;
}
结果:相等
总结:strcpy、strstr、strcat这三个函数在使用的时候,都需要记录首个字符的地址,都是通过’\0’来作为结束条件,返回值都是char *,而strlen、strcmp返回值都是整形。