字符函数和字符串函数

1.strlen求字符串长度
size_t strlen ( const char * str );
(1)字符串将’\0’作为结束标志,strlen函数返回的是在字符串中’\0’前面出现的字符个数(不包含’\0’)
(2)参数指向的字符串必须要以’\0’结束
(3)注意函数的返回值为size_t,是无符号的
strlen函数的模拟实现:

#include<stdio.h>
#include<assert.h>

int my_strlen(const char*str)
{
	assert(str != NULL);
	int count = 0;//计数器
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}

int main()
{
	char string[] = "abcdef";//应将字符串放入一个字符型数组中
	int ret = 0;
	ret = my_strlen(string);
	printf("字符串长度为:%d\n",ret);

	system("pause");
	return 0;
}

2.strcpy拷贝
char * strcpy ( char * destination, const char * source );
(1)源字符串必须以’\0’结束。
(2)会将原字符串中的’\0’拷贝到目标空间。
(3)目标必须足够大,以确保能存放源字符串。
(4)目标空间必须可变。
strcpy函数的模拟实现:

#include<stdio.h>
#include<assert.h>

char *my_strcpy(char *dst, const char *src)
{
	char *ret = dst;//将目标空间的起始地址,保存在临时变量ret中,方便函数或系统进行链式调用。
	assert(dst != NULL);
	assert(src != NULL);
	while (*dst = *src)//'='是为了保证在进行拷贝的时候,也同时把\0拷贝到目标空间,完成拷贝。
	{
		dst++;
		src++;
	}
	return ret;
}

int main()
{
	char arr1[7] = "abcdef";
	char arr2[20] = { 0 };
	printf("%s\n", my_strcpy(arr2, arr1));

	system("pause");
	return 0;
}

3.strcat拼接(拼接也是拷贝)
char * strcat ( char * destination, const char * source );
(1)源字符串必须以’\0’结束。
(2)目标空间必须足够大,能容纳下源字符串的内容。(需要dst预留足够的空间,容纳拷贝内容)
(3)目标空间必须可以修改。
stract函数的模拟实现:

#include<stdio.h>
#include<assert.h>

char* my_strcat(char *dst, const char *src)
{
	assert(dst != NULL);
	assert(src != NULL);

	char* ret = dst;

	while (*dst)//*dst即*dst !='\0'
	{
		dst++;
	}
	//dst -> \0
	while (*dst = *src)
	{
		dst++;
		src++;
	}

	return ret;
}

int main()
{
	const char* src = "abcd1234";
	char dst[16] = "XYZ";
	my_strcat(dst, src);
	printf("dst: %s\n", dst);

	system("pause");
	return 0;
}

4.strcmp字符串大小比较
int strcmp ( const char * str1, const char * str2 );
(1)比较规则,从左向右,只要特定字符不相等,哪个字符大,所在的字符串就大和长短无关(ASCII码值比较)
(2)str1>str2,返回大于0的数字;
(3)str1=str2,返回0;
(4)str1<str2,返回小于0的数字。
strcmp函数的模拟实现:

#include<stdio.h>
#include<assert.h>

int my_strcmp(const char *s1, const char *s2)
{
	assert(s1 != NULL);
	assert(s2 != NULL);

	int ret = 0;
	//类型强转
	const unsigned char* _s1 = (const unsigned char*)s1;
	const unsigned char* _s2 = (const unsigned char*)s2;

	//!(ret == (*_s1 - *_s2)):满足,说明*_s1 == *_s2 
	while (!(ret = (*_s1 - *_s2)) && *_s1)//*_s1即*_s1 !='\0'
	{
		_s1++;
		_s2++;
	}
	if (ret < 0)
	{
		ret = -1;
	}
	else if (ret > 0)
	{
		ret = 1;
	}
	else
	{
		ret = 0;
	}
	return ret;
}

int main()
{
	const char* _s1 = "abcd1236";
	const char* _s2 = "abcd1234";
	int ret = my_strcmp(_s1, _s2);
	printf("%d\n", ret);

	system("pause");
	return 0;
}

5.strstr查找功能
const char * strstr ( const char * str1, const char * str2 );
char * strstr ( char * str1, const char * str2 );
strstr函数的模拟实现:

#include<stdio.h>
#include<assert.h>

//target: 目标字符串,被查找的
//sub: 查找子串,需要查找的
//return NULL, not found else found it!
const char* my_strstr(const char *target, const char *sub)
{
	assert(target != NULL);
	assert(sub != NULL);

	//->target
	const char* start = target;
	const char* move = NULL;
	//->sub
	const char* sub_start = NULL;

	//整体移动的
	while (*start)
	{
		sub_start = sub;
		move = start;
		//局部比较的
		while (*start && *move && *move == *sub_start)
		{
			move++;
			sub_start++;
		}
		//
		if (*sub_start == '\0')
		{
			return start;
		}
		//not found
		start++;
	}

	return NULL;
}

int main()
{
	const char* target = "abc123abcd4567123xyz";
	const char* sub_str = "xyz";
	printf("%s\n", my_strstr(target, sub_str));

	system("pause");
	return 0;
}

6.memcpy复制功能
void * memcpy ( void * destination, const void * source, size_t num );
(1)函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
(2)这个函数在遇到’\0’的时候并不会停下来。
(3)如果source和destination有任何的重叠,复制的结果都是未定义的。
memcpy函数的模拟实现:

#include<stdio.h>
#include<assert.h>

void* my_memcpy(void *dst, const void *src, size_t num)
{
	assert(dst != NULL);
	assert(src != NULL);
	if (num == 0)
	{ //TODO
		return dst;
	}

	unsigned char* _dst = (unsigned char*)dst;
	unsigned char* _src = (unsigned char*)src;

	while (num)
	{
		*_dst = *_src;
		_dst++;
		_src++;
		num--;
	}
	return dst;
}

int main()
{
	char src[32] = "abcdefg";
	char dst[32] = { 0 };
	my_memcpy(src, src + 1, strlen(src));
	my_memcpy(src+ 1, src , strlen(src) + 1);//出现内存重叠问题
	printf("%s\n", src);

	system("pause");
	return 0;
}

7.memmove复制功能
void * memmove ( void * destination, const void * source, size_t num );
(1)和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的(新版本编译器两个函数都可以)。
memmove函数模拟实现:

#include<stdio.h>
#include<assert.h>

void *my_memmove(void *dst, const void *src, int num)
{
	assert(dst != NULL);
	assert(src != NULL);

	if (num <= 0) {
		return NULL;
	}

	//字节单位
	unsigned char* _dst = (unsigned char*)dst;
	unsigned char* _src = (unsigned char*)src;

	if (_dst > _src && _dst < _src + num) {
		//right->left
		_src = _src + num - 1;
		_dst = _dst + num - 1;

		while (num) {
			*_dst = *_src;
			_dst--;
			_src--;
			num--;
		}
	}
	else {
		while (num) {
			*_dst = *_src;
			_dst++;
			_src++;
			num--;
		}
	}

	return dst;
}

int main()
{
	char src[32] = "abcdefg";
	char dst[32] = { 0 };
	my_memmove(src, src + 1, strlen(src));
	printf("%s\n", src);

	system("pause");
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值