本文按功能的不同来介绍不同字符串函数的功能、模拟实现以及操作细节。
1.strlen函数
原型:
size_t strlen( const char *string );
介绍:
①该函数可以计算目标字符串的长度,具体从首元素开始计算,直到遇到'\0'时停下('\0'不计数)
②返回类型:size_t
注意:size_t是无符号长整型类型,这决定了strlen函数的返回值不能为负,忽略这点可能会导致如下结果:
#include <stdio.h>
int main()
{
const char* str1 = "abcdef";
const char* str2 = "bbb";
if (strlen(str2) - strlen(str1) > 0)
{
printf("str2>str1\n");
}
else
{
printf("srt1>str2\n");
}
return 0;
}
模拟实现:
方法一:
size_t my_strlen(const char* string)
{
assert(string);
int count = 0;
while (*string != '\0')
{
string++;
count++;
}
return count;
}
方法二:
size_t my_strlen(const char* string)
{
assert(string);
if (*string != '\0')
{
return 1 + my_strlen(string + 1);
}
return 0;
}
方法三:
size_t my_strlen(const char* string)
{
assert(string);
char* ret = string;
while (*string != '\0')
{
string++;
}
return string - ret;
}
2 .strcpy函数
原型:
char*strcpy(char*destination,const char*sourse);
介绍:
①该函数会将源字符串(sourse)连同字符串中第一个'\0'一起拷贝覆盖到目标空间(destination)
②返回类型:char*
注意:源字符串(sourse)一定要以'\0'为结尾,目标空间(destination)大小一定要足以让源字符串得以拷贝覆盖过去,并且目标空间一定要是可变的。
#include <stdio.h>
#include <string.h>
int main()
{
char* str1 = "hello world";
char str2[10] = "*********";
printf("%s\n", strcpy(str1,str2));
return 0;
}
这样的写法是错误的。这里的str1指向常量字符串,因此这里的目标空间是不可变的。
模拟实现:
#include<stdio.h>
#include<assert.h>
#include<string.h>
char* my_strcpy(char* destination, const char* sourse)
{
assert(destination && sourse);
char* ret = destination;
while (*destination++ = *sourse++ )
{
;
}
return ret;
}
int main()
{
char des[20] = { 0 };
char* sourse = "abcd";
printf(my_strcpy(des, sourse));
return 0;
}
3.strcat函数
原型:
char*strcat(char*destination,const char*sourse)
介绍:
功能与strcpy类似,都是从把源字符串拷贝覆盖到目标空间,但不同的是strcat是将源字符串追加到目标字符串的后面。
注意:源字符串(sourse)一定要以'\0'为结尾,目标空间(destination)大小一定要足以让源字符串得以拷贝覆盖过去,并且目标空间一定要是可变的。不能够自己给自己追加!
模拟实现:
char* my_strcat(char* destination, const char* sourse)
{
assert(destination && sourse);
char* ret = destination;
while (*destination)
{
destination++;
}
while (*destination++ = *sourse++)
{
;
}
return ret;
}
int main()
{
char des[20] = "abcd";
char* sourse = "efg";
printf(my_strcat(des, sourse));
return 0;
}
4.strcmp函数
函数原型:
int strcmp(const char*str1,const char*str2)
函数功能:
int my_strcmp(const char* str1, const char* str2)
{
assert(str1&&str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
}
if (str1 > str2)
{
return 1;
}
else
return -1;
}
5.strncpy函数
函数原型:
char*strncpy(char*destination,char*sourse,size_t num)
#include <stdio.h>
#include<assert.h>
#include<string.h>
char*my_strncpy(char* destination, const char* sourse,size_t num)
{
assert(destination&&sourse);
char* ret = destination;
while (num && *sourse)
{
*destination++ = *sourse++;
num--;
}
while (num--)
{
*destination++ = '\0';
}
return ret;
}
int main()
{
char des[20] = "12345 world";
char* sourse = "hello world";
printf(my_strncpy(des, sourse, 5));//
return 0;
}
6.strncat函数
函数原型:
char*strncat(char*destination,const char*sourse,size_t num)
介绍:与strcat的差别同理于strncpy与strcpy的差别。
模拟实现:
char*my_strncat(char* destination, const char* sourse,size_t num)
{
assert(destination&&sourse);
char* ret = destination;
while (*destination)
{
destination++;
}
while (num && *sourse)
{
*destination++ = *sourse++;
num--;
}
*destination = '\0';
return ret;
}
int main()
{
char des[20] = "hello ";
char* sourse = "world1234";
printf(my_strncat(des, sourse, 5));//
return 0;
}
7.strncmp函数:
函数原型:
int strncmp(const char*str1,const char*str2,size_t num)
模拟实现:
#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strncmp(const char* str1, const char* str2, size_t num)
{
assert(str1&&str2);
while (num--)
{
if (*str1 == *str2)
{
str1++;
str2++;
}
else
{
if (*str1 > *str2)
{
return 1;
}
else
{
return -1;
}
}
}
return 0;
}
8.strstr函数
函数原型:
char*strstr(const char*str1,const char*str2)
功能:strstr()是一个参数为两个字符指针类型,返回值是char*类型的函数,它用于找到子串(str2)在一个字符串(str1)中第一次出现的位置
模拟实现:
#include <stdio.h>
#include <assert.h>
#include<string.h>
char* my_strstr(const char* p1, const char*p2)
{
assert(p1&&p2);
char*s1 = NULL;
char*s2 = NULL;
char*cur = p1;
if (*p2 == '\0')
{
return (char*)p1;
}
while (*cur)//cur代表指向的是子串第一次出现的首元素地址
{
s1 = cur;
s2 = (char*)p2;
while ((*s1 != 0) && (*s2 != 0) && *s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return (char*)cur;
}
if (*s1 == '\0')
{
return NULL;
}
cur++;
}
return NULL;
}
int main()
{
const char* arr1 = "abbbcdefg";
const char* arr2 = "bbc";
char* ret = my_strstr(arr1, arr2);
if (ret == NULL)
{
printf("子串不存在\n");
}
else
{
printf("找到了 子串为:%s\n", ret);
}
return 0;
}
9.memcpy函数
函数原型:
void*memcpy(void*destination,const void*sourse,size_t num);
void* my_memcpy(void* destination, const void* sourse, size_t num)
{
assert(destination && sourse);
void* ret = destination;
while (num--)
{
*(char*)destination = *(char*)sourse;
destination = (char*)destination + 1;
sourse = (char*)sourse + 1;
}
return ret;
}
struct {
char name[40];
int age;
} person, person_copy;
int main()
{
char myname[] = "Pierre de Fermat";
my_memcpy(person.name, myname, strlen(myname) + 1);
person.age = 46;
my_memcpy(&person_copy, &person, sizeof(person));
printf("person_copy: %s, %d \n", person_copy.name, person_copy.age);
return 0;
}
10.memmove函数
void* my_memmove(void* dst, const void* src, size_t count)
{
void* ret = dst;
if (dst < src)
{
while (count--)
{
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
}
else
{
while (count--)
{
*((char*)dst + count) = *((char*)src + count);
}
}
return ret;
}