1.strlen
功能:字符串有多少个字符(到 '\0' 前结束)
size_t strlen ( const char * str );
输入参数:
str:需要判断的字符串的起始位置
返回参数:
字符串的个数(unsign int类型)
模拟实现:
int my_strlen(const char * str)
{
int count = 0;
while(*str)
{
count++;
str++;
}
return count;
}
2.strcpy
功能:复制一个字符串的内容到另一个字符串中去
char* strcpy(char * destination, const char * source );
输入参数:
source:源字符串需要背复制的内容首元素地址
返回参数:
destination:目标字符串需要得到复制内容首元素地址
模拟实现:
char *my_strcpy(char *dest, const char*src)
{
char *ret = dest;
assert(dest && src);
while((*dest++ = *src++))
{
;
}
return ret;
}
3.strcat
功能 :将一个字符串接入一个字符串后
char * strcat ( char * destination, const char * source );
输入参数:
source:需要被加入到另一个字符串后的原字符串地址
返回参数:
destination:被接入的字符串的地址
模拟实现:
char* my_strcat(char* des, const char* sou)
{
assert(des && sou);
char* ret = des;
while (*des != 0)
{
des++;
}
while (*des++ = *sou++)
;
return ret;
}
4.strcmp
功能:比较两个字符串的大小,依次从前向后比较单个字符大小
int strcmp ( const char * str1, const char * str2 );
返回参数:
返回的参数如果大于零则前一个大,如果小于零则后面一个大,等于则两个字符串一样
模拟实现:
int my_strcmp(const char* str1, const char* str2)
{
while (*str1++ == *str2++)
{
;
}
return *str1 - *str2;
}
5. strncpy,strncat,strncat,strncmp的介绍
strncpy,strncat,strncat,strncmp四个函数的功能与没有n的功能基本一致
特别的:上面四个函数可以实现字符串自己与自己的函数实现,如果使用不带n的函数可能会出现函数中目标区域与源区域重合导致的赋值无法识别\0而出现死循环的状况
6.strstr
功能:找到与目标字符串相同的目标字符串的子字符串的地址
char * strstr ( const char *str1, const char * str2);
输入参数:
str1:判断是否有子字符串的字符串
str2:源字符串
返回参数:
如果找到的,输出子字符串的首元素地址;找不到输出NULL(空指针)
模拟实现:
const char* my_strstr(const char* str1,const char* str2)
{
assert(str1 && str2);
char* p1 = str1;
char* p2 = str2;
while (*p1)
{
str1 = p1;
str2 = p2;
while (*str1++ == *str2++)
{
if (*str2 == '\0')
{
return p1;
}
}
p1++;
}
return NULL;
}
7.strtok
功能:分割字符串
char * strtok ( char * str, const char * sep );
输入参数:
str:目标字符串的首元素地址
sep:分割标记
返回参数:
返回被分割的字符串
8.strerror
功能:如果编程错误返回错误的信息对应的错误码
char * strerror ( int errnum )
输入参数:
errnum:编程错误码对应的数字
返回参数:
返回错误码
演示:
//引用需要包含的头文件
#include<errno.h>
#include<string.h>
//打印上面代码出错的原因
printf("%s",strerror(errno));
9.memcpy
功能:与strcpy差不多,但是strcpy只用于字符串;memcpy适用于所有类型
void * memcpy ( void * destination, const void * source, size_t num );
输入参数:
num:需要被复制的目标需要多少字节
void* my_memcpy(void* str1,const void* str2, int num)
{
assert(str1 && str2);
void* ret = str1;
for (int i = 0; i < num; i++)
{
*(char*)str1 = *(char*)str2;
str1 = (char*)str1 + 1;
str2 = (char*)str2 + 1;
}
return ret;
}
为什么str1和str2为void*类型?
为了做到普适性,编译器不能针对某个特定的类型设置大小,所有用void*表示所有都可以用
为什么函数内要变为char*来实现?
因为当把大小定为一个字节时这样就可以将所有的内存内容拷贝下来
特别的,返回的地址如果要使用,请记得类型转换
10.memmove
功能:与memcpy功能差不多,但是memcpy可能在对自身字符串与自身字符串复制出现死循环
void * memmove ( void * destination, const void * source, size_t num );
当两个区域块有重合如何进行复制?
不难发现,其实可以通过分类讨论来实现,1.如果源字符串首字符大于目标字符串首字符,可以从后往前赋值;2.如果源字符串首字符小于目标字符串首字符,可以从前往后赋值
void my_memmove(void* str1,void* str2,size_t num)
{
assert(str1 && str2);
void* ret = str1;
if (str1 < str2)
{
while (num--)
{
*(char*)str1 = *(char*)str2;
str1 = (char*)str1 + 1;
str2 = (char*)str2 + 1;
}
}
else
{
while (num--)
{
*((char*)str1 + num) = *((char*)str2 + num);
}
}
return ret;
}
11.memcmp
功能:与strcmp类似
int memcmp ( const void * ptr1,const void * ptr2,size_t num );