C语言中的常见字符串操作函数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Qiana_/article/details/81737821

以下函数的头文件位于#include<string.h>

1.strcat函数:

函数原型:char * strcat ( char * destination, const char * source );

该函数是字符串拼接函数。将源字符串拼接至目标字符串的结尾处。要覆盖目标字符串中的'\0'。

source和destination的空间不能重叠,而且destination的空间一定要能够容纳destination和source,否则在进行指针++的时候就会出错。

模拟实现:

char* mystrcat(char* dest,const char* src)
{
	char* p = dest;
	assert(dest && src);
	//找dest的结尾处,最终指向'\0'
	while(*dest != '\0')
		dest++;
	while(*src != '\0')
		*dest++ = *src++;
	*dest = '\0';
	return p;
}

int main()
{
	//目标串中的空间一定要开够,否则指针++会出错
	char str1[30] = "hello"; 
	char* str2 = " world";
	char* ret = mystrcat(str1,str2);
	printf("%s\n",ret);
	return 0;
}

2.strncat函数:

函数原型:char * strncat ( char * destination, const char * source, size_t num );

该函数实现规定长度的字符串的拼接。和strcat不同之处在于,需要加一个循环,循环次数为len次。

//strncat
char* mystrncat(char* dest,const char* src,int len)
{
	char* p = dest;
	assert(dest);
	assert(src);
	while(*dest)
		dest++;
	while(len--)
	{

		*dest = *src;
		dest++;
		src++;
	}
	*dest = '\0';
	return p;
}

int main()
{
	char str1[30] = "hello ";
	char str2[] = "the beautiful";
	char* ret = mystrncat(str1,str2,3);
	printf("%s\n",ret);
	return 0;
}

3.memchar函数:

函数原型:

const void * memchr ( const void * ptr, int value, size_t num );
      void * memchr (       void * ptr, int value, size_t num );

该函数是规定的范围内查找一个值,返回这个值的位置。

模拟实现:

//memchr
void* mymemchr(const void* str,int value,size_t n)
{
	char* p = (char*)str;
	assert(str);
	while(n--)
	{
		if((char)value == *p)
			return p;
		else
			++p;
	}
	return NULL;
}
int main()
{
	char* p;
	char str1[] = "maybe is you!";
	p = mymemchr((void*)str1,'i',sizeof(str1));
	printf("value is %c, position is %d\n",*p,p-str1+1);
	return 0;
}

3.memcpy函数:

函数原型:

void * memcpy ( void * destination, const void * source, size_t num );

该函数是内存拷贝函数,从数据源拷贝num个字节的数据到目标数组。

注意:传destination的实参的时候不能传指针。destination是指向目标数组的指针,数组名做参数,传的是数组首元素的首地址。当传的是一个指针的时候,就会出错,指针未初始化的时候,指向一个未知的区域,里面有随机值,且不知道大小和数据类型,当源数据对它进行赋值的时候,会出错所以memcpy的第一个参数,传一个大小大于源数据的数组。

#include<stdio.h>
#include<string.h>
#include<assert.h>
 
void* mymemcpy(void* desc,const void* src,size_t size)
{
	void* ret = desc;
	char* str1 = (char*)desc;
	char* str2 = (char*)src;
	assert(str1);
	assert(str2);
	while(size--)
	{
		*str1++ = *str2++;
	}
	return ret;
}
 
int main()
{
	char s1[] = "hello world";
	char s2[20];
	int a1[] = {1,2,3,4,5,6,7,8,9};
	int a2[10];
	mymemcpy(s2,s1,sizeof(s1));
	std::cout<<s2<<std::endl;

	mymemcpy(a2,a1,sizeof(a1));
	int size = sizeof(a1)/sizeof(a1[0]);
	for(int i = 0;i < size;++i)
	{
		std::cout<<a2[i]<<" ";
	}
	std::cout<<std::endl;
	return 0;
}

更加详细讲解见:https://blog.csdn.net/Qiana_/article/details/79951106

4.memmove函数:

函数原型:

void * memmove ( void * destination, const void * source, size_t num );

该函数是内存移动函数,从source所指向的对象复制num个到destination所指向的对象,允许内存重叠。

内存重叠:例如,char s1[] = "123456789" ,复制“3456”到“5678”,“56”是重叠部分,若用memcpy拷贝,将“34”拷贝到了“56”的位置,导致将“56”拷贝到“78”时,“56”已经不存在了,被“34”覆盖了。而memmove就是解决memcpy不能内存重叠的问题,比memcpy更加的安全。如果目标区域和源区域没有重叠,则memmove和memcpy的函数作用相同。

模拟实现:

当存在重叠的部分时,从尾部到头开始拷贝。不存在重叠时,就和memcpy的实现是一样的。全都用从尾到头拷贝就好了,为什么还要分开写?如果没有重叠的时候,两部分的位置是没有关系的,用num(个数)是没法找到尾部的。

void* my_memmove(void* desc,const void* src,size_t num)
{
	void* ret = desc;
	char* str1 = (char*)desc;
	char* str2 = (char*)src;
	assert(str1);
	assert(str2);
	if(str1 > str2)
	{
		while(num--)  //循环num次,由num=num-1到num=0
		{
			*(str1+num) = *(str2+num);
		}
	}
	else
	{
		while(num--)
		{
			*str1++ = *str2++;
		}
	}
 
	return ret;
}
 
int main()
{
	char s1[] = "123456789";
	my_memmove(s1+4,s1+2,4);
	std::cout<<"s1: "<<s1<<std::endl;
 
	return 0;

5.memcmp函数:

函数原型:

int memcmp ( const void * ptr1, const void * ptr2, size_t num );

内存比较函数,该函数用来比较ptr1,ptr2,ptr1和ptr2可以是字符串也可以是整型,比较的长度为num个字节,返回值有三个:

<0 , ptr1小于ptr2的;

=0,ptr1指向的内容等于ptr2指向的内容;

>0,ptr1指向内容大于 ptr2指向的内容。

模拟实现:

//memcmp
int my_memcmp(const void* ptr1,const void* ptr2,size_t num)
{
	char* dest = (char*)ptr1;
	char* src = (char*)ptr2;
	assert(ptr1 && ptr2);

	while(num && *dest == * src)
	{
		num--;
		dest--;
		src--;
	}

	if(num == 0)
		return 0;
	else
		return *dest-*src-'\0';
}
int main()
{
	//比较字符串
	char str1[] = "prant";
	char str2[] = "prant house";

	//比较整型
	int a1[] = {1,2,3,4,6,7};
	int a2[] = {1,2,3,4,9,12};

	int ret = my_memcmp(str1,str2,5);
	printf("string is %d\n",ret);

	ret = my_memcmp(a1,a2,4);
	printf("int is %d\n",ret);
	return 0;
}

6.memset函数:

函数原型:

void * memset ( void * ptr, int value, size_t num );

该函数用于初始化,将ptr所指向的空间的num字节的大小初始化为value.

模拟实现:

//memset:初始化
void* my_memset(void* ptr,int value,size_t num)
{
	char* p = (char*)ptr;
	assert(p);
	while(num--)
	{
		*p = (char)value;
		p++;
	}
	return ptr;
}

int main()
{
	char str1[] = "hello world";
	my_memset(str1,0,5);
	printf("%s\n",str1);
	return 0;
}

 

7.strchr函数:

函数原型:

const char * strchr ( const char * str, int character );
      char * strchr (       char * str, int character );

该函数的功能是在str中查找character,返回在字符串中第一次出现character的位置.

模拟实现:

//strchr : 查找字符的位置
char* my_strchr(const char* str,int character)
{
	assert(str);
	while(*str && (*str != (char)character))
		++str;
	//包含了character和str都为0的情况
	if((char)character == *str)
		return (char*)str;
	return NULL;
}
int main()
{
	char str1[] = "programming";
	char* pch;
	printf("There is the 'r' in \"%s\"\n",str1);
	pch = strchr(str1,'r');
	while(pch != NULL)
	{
		printf("found at %d\n",pch-str1+1);
		pch = strchr(pch+1,'r');
	}
	return 0;
}

   

8.strcpy函数:

函数原型:

char * strcpy ( char * destination, const char * source );

该函数是拷贝字符串函数,将source拷贝到destination,不允许有内存重叠。且destination的空间必须要能容纳source,否则会出错。

模拟实现:

//strcpy:字符串拷贝
char* my_strcpy(char* dest,const char* src)
{
	char* p = dest;
	assert(dest && src);
	while(*dest++ = *src++)
	{
		;
	}
	return p;
}

int main()
{
	char str[30] = {0};
	char* str2 = "hello";
	printf("%s\n",my_strcpy(str,str2));
	return 0;
}

9.strnchr函数:

函数原型:

const char * strrchr ( const char * str, int character );
      char * strrchr (       char * str, int character );

在str所指向的空间中,查找最后一次出现character的位置。

模拟实现:

//strrchr
//从头往后找
char* my_strrchr(const char* str,int character)
{
	char* ret = NULL;
	assert(str);
	while(*str)
	{
		if(*str == (char)character)
		{
			ret = (char*)str; //ret保存出现character的位置
			++str;
		}
		else
			++str;
	}
	if((char)character == *str)
		ret = (char*)str;
	return ret;
}

////从后往头找
char* myy_strrchr(const char* str,int character)
{
	char* ret = str;
	while(*str)
		++str; //找到最后一个字符
	while(*str != (char)character && (str >= ret))
		--str;  //找到第一个等于character的位置
	if(str >= ret)
		return (char*)str;
	return NULL;
}

int main()
{
	char str1[] = "programming";
	char* pch;
	printf("There is the 'r' in \"%s\"\n",str1);
	pch = my_strrchr(str1,'r');
	printf("found at %d\n",pch-str1+1);

	pch = myy_strrchr(str1,'r');
	printf("found at %d\n",pch-str1+1);
	return 0;
}

10.strstr函数:

函数原型:

const char * strstr ( const char * str1, const char * str2 );
      char * strstr (       char * str1, const char * str2 );

该函数的功能是寻找子串,在str1中查找str2,返回第一次出现str2的位置的指针。比如"aaaabbbccd",子串"bbc",返回"bbccd",返回找到子串的第一个位置之后的字符串。

模拟实现:

//strstr:寻找子串
char* my_strstr(const char* str1,const char* str2)
{
	char* start = (char*)str1; //用来记录子串的第一个出现的位置
	char* substr = (char*)str2;
	char* cur = (char*)str1; //用来记录当前的位置
	assert(str1);
	assert(str2);
	while(*start)
	{
		cur = start;
		while(*cur != '\0' && *substr != '\0' && *cur == *substr)
		{
			cur++;
			substr++;
		}
		if(*substr == '\0')
			return start;
		substr = (char*)str2;
		start++; //如果没有匹配到,就进行下一轮循环
	}
	return NULL;
}
int main()
{
	char str1[] = "aaaabbbccd";
	char str2[] = "bbc";
	char* ret = my_strstr(str1,str2);
	printf("%s\n",ret);
	return 0;
}

11.strcmp函数

函数原型:

int strcmp ( const char * str1, const char * str2 );

该函数实现字符串的比较,str1小于str2,返回<0 ; str1 等于 str2,返回=0;str1 大于 str2 ,返回>0.

//strcmp
int my_strcmp(char* str1,char* str2)
{
	assert(str1 && str2);
	while(*str1 == *str2)
	{
		if(*str1 == '\0')
			return 0;
	}

	return *str1-*str2;
}

int main()
{
	char str1[] = "hello";
	char str2[] = "china";
	int ret = my_strcmp(str1,str2);
	printf("%d\n",ret);
	return 0;
}

12.strncmp函数

函数原型:

int strncmp ( const char * str1, const char * str2, size_t num );

该函数的功能是num个字节的字符串的比较。str1,str2为需要比较的字符串,num为要比较的字符的数目。

//strncmp
int my_strncmp(const char* str1,const char* str2,size_t num)
{
	assert(str1);
	assert(str2);
	while(num--)
	{
		if(*str1 == *str2)
		{
			str1++;
			str2++;
		}
		else
		{
			return *str1-*str2;
		}
	}
	return 0;
}

int main()
{
	char str1[] = "hello";
	char str2[] = "hellings";
	int ret = my_strncmp(str1,str2,5);
	printf("%d\n",ret);
	return 0;
}

string.h的常见库函数的模拟实现就这么多了,在此一并总结!(*^▽^*)!

猜你喜欢

转载自blog.csdn.net/Qiana_/article/details/81737821
今日推荐