有关字符串的函数(strlen、strcat、strcpy、strcmp、strncat、strncpy、strncmp、 strchr、strrchr、strpbrk、strstr、strrstr、memcpy、memmove)
#pragma once
#include<assert.h>
#include<string.h>
//求取字符串的长度
//1. 利用递归方法实现
int my_strlen1(char* p)
{
if(*p != '\0')
{
return 1+my_strlen1(p+1);
}
else
{
return 0;
}
}
//2. 利用计数法实现
int my_strlen2(char* p)
{
int count = 0;
assert(p);
while(*p)
{
count++;
p++;
}
return count;
}
//3. 利用指针实现
int my_strlen3(const char* p)
{
const char* ret = p;
assert(p);
while (*p)
{
p++;
}
return p-ret;
}
//实现字符串的拷贝(简便写法)
char *my_strcpy(char* dest,const char* src)//返回值设置为char*,以便于链式访问
{
char* ret = dest;
assert(dest);
assert(src);
while(*dest++ = *src++)
{
;
}
return ret;//返回第一个参数的一份拷贝,即一个指向目标字符串的指针
}
//连接字符串
char *my_strcat(char* dest,const char* src)//字符串的连接
{
char* ret = dest;
assert(dest);
assert(src);
while (*dest)
{
dest++;
}
while (*src)
{
*dest++ = *src++;
}
*dest = '\0';//结束标志
return ret;//返回第一个参数的一份拷贝,即一个指向目标字符串的指针
}
//字符串的比较
//如果str1小于str2,函数返回一个小于0的值,如果str1>str2,函数返回一个大于0的值,若两个字符串相等,返回0
int my_strcmp(const char* str1,const char* str2)
{
while (*str1 == *str2)
{
if(*str1 == '\0')
return 0;
str1++;
str2++;
}
return *str1 - *str2;
}
//长度受限的字符串函数
char* my_strncpy(char* dest,const char* src,size_t len)//拷贝长度为len的字符串
{
char* ret = dest;
assert(dest);
assert(src);
while(len--)
{
*dest = *src;
dest++;
src++;
}
*dest = '\0';
return ret;
}
//在目标字符串后面链接长度为len的字符串
char* my_strncat(char* dest,const char* src,size_t len)
{
char* ret = dest;
assert((dest != NULL)&&(src != NULL));
while(*dest != '\0')
{
dest++;
}
while ((len>0) && ((*dest++ = *src++) != '\0'))
{
len--;
}
*dest = '\0';
return ret;
}
//比较两个字符串,但他最多比较len个字节,如果两个字符串在第len个字符之前存在不相等的字符,则像strcmp一样停止比较,返回结果,如果两个字符串的前len个字符相等,则返回0
int my_strncmp(const char* str1,const char* str2,size_t len)
{
assert(str1);
assert(str2);
while (((len--)>0) && (*str1 != '\0') && (*str2 != '\0'))
{
if(*str1 == *str2)
{
str1++;
str2++;
}
else
{
return *str1 - *str2 - '\0';
}
}
return *str1 - *str2 - '\0';
}
//字符串查找
//该函数在字符串str中查找字符ch第一次出现的位置,若找到函数返回一个指向该位置的指针,反之,返回NULL
char* my_strchr(char* str,int ch)
{
char* ret = str;
assert(str);
while (*ret != '\0')
{
if(*ret == ch)
{
return ret;
}
ret++;
}
return NULL;
}
//该函数与strchr函数功能基本一致,只是他返回一个指向该字符串中该字符最后一次出现的位置(最右边的那个)
char* my_strrchr(char* str,int ch)
{
register char* last = NULL;
register char* current = NULL;
if(ch != '\0')//只有ch不为空字符才可以进行查找
{
current = my_strchr(str,ch);
while (current != NULL)
{
last = current;
current = my_strchr(last+1,ch);
}
}
return last;
}
//该函数返回一个指向str中第一个匹配group中任何一个字符的字符位置,若没找到,返回NULL
char* my_strpbrk(char* str,char* group)
{
register char* s1 = str;
register char* s2 = group;
assert(str);
assert(group);
while (*s1 != '\0')
{
while (*s2 != '\0')
{
if(*s1 == *s2)
{
return s1;
}
s2++;
}
s2 = group;
s1++;
}
}
//在str1中查找整个str2第一次出现的起始位置,并返回一个指向该位置的指针
char* my_strstr(char* str1,char* str2)//查找子字符串
{
char* ptr = str1;
char* p1 = NULL;
char* p2 = NULL;
while (*ptr)
{
p1 = ptr;
p2 = str2;
while (*p1 == *p2)
{
++p1;
++p2;
if(*p2 == '\0')
{
return ptr;
}
}
ptr++;
}
return NULL;
}
//在字符串s1中查找字符串s2最右出现的位置,并返回一个指向该位置的指针
char* my_strrstr(char* s1,char* s2)
{
register char* last = NULL;
register char* current = NULL;
//把指针初始化为我们已找到的前一次匹配的位置
//只在第二个字符串不为空时才进行查找,如果为空,返回NULL
if(*s2 != '\0')
{
current = my_strstr(s1,s2);
//我们每次找到字符串时,让指针指向他的起始位置,然后查找该字符串下一个匹配位置
while (current != NULL)
{
last = current;
current = my_strstr(last+1,s2);
}
}
//返回指向我们找到的最后一次匹配的起始位置的指针
return last;
}
//内存拷贝函数
void* memcpy(void* buf1,void* buf2,int count)
{
char* dest = (char*)buf1;
char* src = (char*)buf2;
assert(buf1);
assert(buf2);
while (count--)
{
*dest++ = *src++;
}
return buf1;
}
//必须考虑内存是否有重叠
void* memmove(void* buf1,const void* buf2,int count)
{
char* dest = (char*)buf1;
char* src = (char*)buf2;
assert(buf1);
assert(buf2);
if(dest>src && dest<(src+count))
{
while (count--)
{
*(dest+count) = *(src+count);
}
}
else
{
while (count--)
{
*dest++ = *src++;
}
}
return buf1;
}