c::你了解str--家族吗?

我总结下关于string家族,此家族比较庞大,比较重要,同时也是面试官特别常考的一个点,那么现在我就带大家一起走进string家族吐舌头

1、strcpy

   1)原型:char* strcpy(char* dest,const char* src);

    2)作用:把从src地址开始且含有'\0'的字符串复制到以dest开始的地址空间

       【说明】:src和dest所指的内存区域不可以有重叠并且dest有足够的空间来容纳src里的字符串。返回指向dest的指针。

    3)模拟实现: 

#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest,const char* src)
{
	char* ret = dest;
	assert(dest&&src);
	while(*dest++ = *src++)
	{}
	return ret;
}
int main()
{
	char* str = "zadd";
	char a[10] = {0};
	my_strcpy(a,str);
	printf("%s ",a);
	return 0;
}

2、strncpy

  1)原型:char* strncpy(char* dest, const char* src,size_t
   2)作用:将src中的字符串赋值count个到dest中

        【说明】:它和strcpy不同的是,它不是遇到'\0'停止,而是凑够count个字符串才停止。当不够count个时,用‘\0’来进行填充

   3)模拟实现:

#include<stdio.h>
#include<assert.h>
char* my_strncpy(char* dest,const char* src,size_t count)
{
	char* ret = dest;
	assert(dest&&src);
	while(count&&src)
	{
		*dest++ = *src++;
		count--;
	}
	//当要复制的字符个数大于源字符串的个数,后面缺的
	//字符个数用'\0'来补齐
	if(count>0)  
	{
		while(--count)
		{
			*dest++ = '\0';
		}
	}
	return ret;
}
int main()
{
	char* str = "acdse";
	char a[10] = {0};
    my_strncpy(a,str,7);
	printf("%s",a);
	return 0;
}

3、strstr

  1)原型:char* strstr(const char* str,const char* substr)

   2)作用:在str中查找是否存在substr这样的子串,如果存在,那么就返回此子串首次在str中出现的地址,否则返回NULL

   3)模拟实现:

#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str,const char* substr)
{
	char* start = (char*)str;
	char* substart = (char*)substr;
	char* cp = (char*)start;
	while(*cp)
	{
		start = cp;
		while((*start)&&(*substart)&&((*start) == (*substart)))
		{
			start++;
			substart++;
		}
		//到这一步,说明子串已经匹配完毕,所以直接返回在原串中的首地址
		if(*substart == '\0')
			return cp;
		//否则要重新进行查询匹配
		substart = substr;
		cp++;
	}
	return NULL;
}
int main()
{
	char* str = "abcdf";
	char* substr = "bc";
	printf("%s ",my_strstr(str,substr));
	return 0;
}

4、strcat

   1)原型:char* strcat(char* dest,const char* src)

   2)作用:将src里的字符串添加到dest的后面(覆盖dest的'\0')

        【说明】:dest和src所指的区域不可以重叠并且dest有足够的空间可以容纳src,返回指向dest的指针

   3)模拟实现:

#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest,const char* src)
{
	char* ret = dest;
	assert(dest&&src);
	while(*dest)
	{
		dest++;
	}
	while(*dest++ = *src++)
	{}
	return ret;
}
int main()
{
	char* str = "abcdf";
	char a[20] = "erty";
	printf("%s ",my_strcat(a,str));
	return 0;
}

5、strncat

  1)原型:char* strncat(char* dest,const char* src,size_t count)

   2)作用:将src中count个字符添加到dest的后面

   3)模拟实现:

#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest,const char* src,size_t count)
{
	char* ret = dest;
	assert(dest&&src);
	while(*dest)
	{
		dest++;
	}
	while(count&&*src)
	{
		*dest++ = *src++;
		count--;
	}
	if(count>0)
	{
		while(--count)
		{
			*dest++ = '\0';
		}
	}
	return ret;
}
int main()
{
	char* str = "abcdf";
	char a[20] = "erty";
	printf("%s ",my_strcat(a,str,2));
	return 0;
}

6、strcmp

  1)原型:int strcmp(const char* str1,const char* str2)

   2)作用:比较两个字符串的大小,如果str1=str2,则返回0,如果str1>str2则返回正数,否则返回负数

   3)模拟实现

#include<stdio.h>
#include<assert.h>
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 *str1-*str2;
	else
		return -1;
}
int main()
{
	char* s1 = "acvd";
	char* s2 = "ace";
	printf("%d ",my_strcmp(s1,s2));
	return 0;
}

7、strncmp

  1)原型:int strncmp(const char* str1,const char* str2,size_t count)

   2)作用:比较两个字符串中count个字符的大小

   3)模拟实现

#include<stdio.h>
#include<assert.h>
int my_strncmp(const char* str1,const char* str2,size_t count)
{
	assert(str1&&str2);
	while(--count)
	{
		if(*str1==*str2)
		{
			str1++;
			str2++;
		}
		else
		{
			break;
		}
	}
	return *str1-*str2;
}
int main()
{
	char* s1 = "abc";
	char* s2 = "ab";
	printf("%d",my_strncmp(s1,s2,2));
}

8、strlen

   1)原型:size_t strlen(const char* str)

   2)作用:计算字符串的长度,但是不包括'\0'

   3)模拟实现:

//两种方法
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* str)
{
     方法一:普通的计数
	/*size_t len = 0;
	assert(str);
	while(*str++ != '\0')
	{
		len++;
	}
	return len;
	*/
       方法二:使用递归
	assert(str);
	if(*str!= '\0')
		//return 1+my_strlen(str++);//这块会挂
		return 1+my_strlen(++str);
	else
		return 0;
}
int main()
{
	char* s1 = "abcde";
	printf("%d",my_strlen(s1));
	return 0;
}

9、memcpy

  1)原型:void* memecpy(void* dest,const void* src,size_t count)

   2)作用:C/c++使用的内存拷贝函数,功能是从src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存的起始位置中

   3)模拟实现:

#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest,const void* src,size_t count)
{
	char* pdest = (char*)dest;
	char* psrc = (char*)src;
	char* ret = pdest;
	while((count--)&&(*pdest++=*psrc++))
		{}
	return ret;
}
int main()
{
	char* s1 = "serwer";
	char a[20] = {0}; 
	printf("%s ",my_memcpy(a,s1,3));
	return 0;
}

10、memmove

  1)原型:void* memmove(void* dest,const char* src,size_t count)
   2)作用:将src中count个字节拷贝到dest中,如果目标区域和源区域有重叠的话,它能够保证在源串被覆盖之前将重叠区域拷贝到目标区域,但是src的内容会发生变化。如果没有重叠区域,那么它的功能和memcpy的作用是一样的

   3)图示说明这个函数怎么回事:、


   4)模拟实现:

#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest,const void* src,size_t count)
{
	char* pdest = (char*)dest;
	char* psrc = (char*)src;
	char* ret = (char*)dest;
	while(count--)
	{
		if((pdest>psrc) && (pdest<psrc+count))
		{
			*(pdest+count) = *(psrc+count);
		}
		else
		{
			*pdest++ = *psrc++;
		}
	}
	return ret;
}
int main()
{
	char* s1 = "serwer";
	char a[20] = {0}; 
	printf("%s ",my_memmove(a,s1,3));
	return 0;
}

11、strcpy和memcpy的区别:

1) strcpy提供了字符串的复制。即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制字符串的结束符。
2)memcpy提供了一般内存的复制。即memcpy对于需要复制的内容没有限制,因此用途更广。

strcpy和memcpy主要有以下3方面的区别。
1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy

【注意】:memcpy用来在内存中复制数据,由于字符串是以“\0”结尾的,所以对于在数据中包含“\0”的数据只能用memcpy。

Strncpy和memcpy很相似,只不过它在一个终止的空字符处停止。当n>strlen(s1)时,给s2不够数的空间里填充“\0”;当n<=strlen(s1)时,s2是没有结束符“\0”的。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值