关于str家族-创新互联

不受限制的字符串函数,比如说strcpy、strcmp等等,我们最常用的字符串函数都是不受限制的,只是通过寻找字符串参数结尾的NULL字节来判断它的长度。那么什么是受限制的字符串函数呢?通过下面的例子我们来一起详细了解一下

为袁州等地区用户提供了全套网页设计制作服务,及袁州网站建设行业解决方案。主营业务为成都网站设计、做网站、袁州网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

strcpy:

原型:char *strcpy( char *strDestination, const char *strSource );

这个函数把参数src字符串复制到dest参数中,在使用这个函数时需要注意,首先,必须保证目标字符数组的空间足以容纳需要复制的字符串,为什么呢?如果字符串比数组长,多余的字符仍然会被复制,这就导致它们会覆盖原先存储在数组后面的内存空间的值。其次,目标参数应该是可被修改的,所以它必须是个字符数组或者是一个指向动态分配内存的数组的指针。

1.strcpy模拟实现:

char *my_strcpy(char *dest, const char *src)
{
	char *ret = dest;
	assert(src != NULL);
	assert(dest != NULL);
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}

 strncpy:  把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回dest。

 上面是不受限制的字符串函数,那么为什么会有strncpy这样一类受限制的字符串函数呢?

就拿这两个函数来说,strcpy只是复制字符串,但不限制复制的数量,很容易造成缓冲溢出。strncpy要安全一些。strncpy能够选择一段字符输出,strcpy则不能。

下面是strncpy模拟实现:

char *my_strncpy(char *dest, const char *src, int n)
{
	char *ret = dest;
	assert(dest);
	assert(src);
	while (n--)
	{
		*dest++ = *src++;
	}
		*dest = '\0';
	return ret;
}

2.将两个字符串连接,我们可以使用strcat函数

函数原型:

char *strcat( char *strDestination, const char *strSource );

功能:

把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')。

说明:

src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。

返回指向dest的指针。

char *my_strcat(char *dest, const char *src)
{
	char *ret = dest;
	assert(src != NULL);
	assert(dest != NULL);
	while (*dest)
	{
		dest++;
	}
	while (*dest++ = *src++)
		{
			;
		}
	return ret;
}


strncat:

功能

把src所指字符串的前n个字符添加到dest所指字符串的结尾处,并覆盖dest所指字符串结尾的'\0',从而实现字符串的连接。

说明

src和dest所指内存区域不可以重叠,并且dest必须有足够的空间来容纳src的字符串。

返回值

返回指向dest的指针。

char *my_strncat(char *dest, const char *src, int len)
{
	char *ret = dest;
	assert(dest);
	assert(src);
	while (*dest)
	{
		dest++;
	}
	while (len--)
	{
		*dest = *src;
		dest++;
		src++;
	}
	*dest = '\0';
	return ret;
}

3.strcmp函数:比较两个字符串。

有一个需要注意的地方是

当s1

当s1=s2时,返回值= 0;

当s1>s2时,返回正数。

即:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇'\0'为止。

有的人以为返回值是1和-1,分别代表大于和小于,如果你也这样想,那就错了。ANSI标准规定,返回值为正数,负数,0 。而确切数值是依赖不同的C实现的。

int my_strcmp(const char *str1, const char *str2)
{
	assert(str1);
	assert(str2);
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
		if (*str1 - *str2 > 0)
			return -1;
		else
			return 1;
}

strncmp函数原型:

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

 参数str1, str2 为需要比较的两个字符串,n为要比较的字符的数目。

 字符串大小的比较是以ASCII 码表上的顺序来决定,此顺序亦为字符的值。strncmp()首先将s1 第一个字符值减去s2 第一个字符值,若差值为0 则再继续比较下个字符,直到字符结束标志'\0',若差值不为0,则将差值返回。例如字符串"Ac"和"ba"比较则会返回字符"A"(65)和'b'(98)的差值(-33)。注意:要比较的字符包括字符串结束标志'\0',而且一旦遇到'\0'就结束比较,无论n是多少,不再继续比较后边的字符。

strncmp函数模拟实现:

int my_strncmp(const char *dest, const char*src, int count)
{
	assert(dest);
	assert(src);
	while (count>0 && (*dest == *src))
	{
		if (*dest == '\0')
			return 0;
		dest++;
		src++;
		count--;
	}
	return *dest - *src;
}

4.为了在字符串中查找一个子串,我们可以使用strstr函数

函数原型:

char *strstr( const char *string, const char *strCharSet );

这个函数在s1中查找整个s2第一次出现的起始位置,并返回一个指向该位置的指针。如果s2没有完整地出现在s1的任何地方,函数将返回一个NULL指针。如果第二个参数是一个空字符串,函数就返回s1。

char *my_strstr(const char *str, const char *substr)
{
	assert(str != NULL);
	assert(substr != NULL);
	char *s1 = (char *)str;
	char *s2 = (char *)substr;
	char *start = (char *)str;
	while (*start)
	{
		s1 = start;
		while ((*s1 != '\0') && (*s2 != '\0') && (*s1 == *s2))
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return start;
		s2 = (char *)substr;
		start++;
	}
	return NULL;
}

strrstr:

标准库中并不存在这样的函数,当然,如果需要,也可以很容易实现

strrstr函数在字符串s1中查找s2最后出现的位置

char* my_strrstr(char const *s1, char const *s2)
{
	char *last = NULL;  //将指针初始化为已经找到的前一次匹配位置
	char *current = NULL;
	assert(s1);
	assert(s2);
	if (*s2 )  //只有在第二个字符串不为空时才进行查找
	{
		current = (char *)strstr(s1, s2);//s2在s1中第一次出现的位置
		while (current != NULL)
		{
	//每次找到字符串时,让指针指向它的起始位置,然后查找该字符串下一个匹配位置	
			last = current;   
			current = (char*)strstr(last + 1, s2);
		}
	}
	return last;
}

5.在一个字符串中查找一个特定字符最容易的方法是使用strchr函数

这个函数比较简单,下面是模拟实现:

#include
#include

char *my_strchr(const char*str, int ch)
{
	while (*str)
	{
		if (*str == ch)
			return (char*)str;
		str++;
	}
	return NULL;
}
int main()
{
	char *str = "happy";
	char *ret = my_strchr(str, 'a');
	if (ret != NULL)
	{
		printf("%c\n", *ret);
	}
	system("pause");
	return 0;
}

strrchr:

strrchr() 函数查找字符在指定字符串中从后面开始的第一次出现的位置,如果成功,则返回从该位置到字符串结尾的所有字符,如果失败,则返回 false。与之相对应的是strstr()函数,它查找字符串中首次出现指定字符的位置。

函数原型:

char *strrchr( const char *string, int c );

char *my_strrchr(char *str, char ch)
{
	char *ptr = NULL;
	assert(str);
	while (*str)
	{
		if (*str == ch)
			ptr = str;
		str++;
	}
	if (ptr != 0)
		return ptr;
	return 0;
}
int main()
{
	char ch = 0;
	char *ret = NULL;
	char *arr = "feabadc";
	printf("请输入一个你要查找的字符:");
	scanf_s("%c", &ch);
	ret = my_strrchr(arr, ch);
	printf("%s\n", *ret);
	system("pause");
	return 0;
}

当然,关于str这样的函数还有很多,这里模拟实现了一些经常用的函数,希望互相借鉴帮助。

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


新闻名称:关于str家族-创新互联
网页链接:http://azwzsj.com/article/coghss.html