(作业)C语言:atoi和strncpy、strncat、strncmp的模拟实现

1. atoi()实现

atio:将字符串中的字符转为数字

enum Status
{
	VALID,
	INVALID
}status = INVALID;	// 创建枚举变量名status它的值为非法 默认非法省事

int my_atoi(const char* str)
{
	int flag = 1;
	// 空指针
	assert(str);
	// 空字符串
	if (*str == '\0')
	{
		return 0;
	}
	// isspace判断是否是空格的函数
	while (isspace(*str))
	{
		str++;
	}
	// 正负号
	if (*str == '+')
	{
		flag = 1;
		str++;
	}
	else if (*str == '-')
	{
		flag = -1;
		str++;
	}
	long long n = 0;
	while (*str!='\0')
	{
		if (isdigit(*str))
		{
			// 乘以flag,使得负数能加上
			n = n * 10 + flag * (*str - '0');
			// n加完再判断
			if (n < INT_MIN || n > INT_MAX)
			{
				n = 0;
				break;
			}
		}
		else
		{
			break;
		}
		str++;
	}
	if (*str == '\0')
	{
		status = VALID;
	}

	return n;
}

int main()
{
	// atoi把字符串转换成整型数的一个函数
	char arr[20] = "     -1234888";
	int ret = my_atoi(arr);
	if (status == VALID)
	{
		printf("正常转换%d\n", ret);
	}
	else
	{
		printf("非法转换:%d\n", ret);
	}
	return 0;
}

以下都是长度受限制的字符串函数的实现,带n表示需要明确拷贝、追加、比较的长度

2. strncpy:

strcpy():字符串拷贝函数

学会使用 while(*dest++=*src++)

  • 下面是strcpy()的实现
void my_strcpy(char* dest, const char* src)
{
	// 传入错误值报错
	assert(dest && src);
	// 即使最后是\0,也会先赋值,拷贝成功后整体变为0,也会使得while停
	while (*dest++=*src++)
	{;}
}
标准的my_strcpy()会返回目标空间起始地址,所以起始时候拿char* res = dest;return res;

  • strncpy(*dest, *src, int n)的实现:

分两种情况:1. n大于src时,2. n小于等于src时:

  1. src不够,则补’\0’;
  2. 小于或者等于就全复制,等于的话,dest会把src的’\0’也全复制上。但是小于的话,给src下一位变为‘\0’,不然会漏。
void my_strcnpy(char* dest, char* src, int n)
{
	assert(dest && src);
	// 这里没有src长度,只要src存在,就进来做
	while(*src)
	{
		while (*dest++ = *src++)
		{
			// 外面做条件的时候,已经复制了一次。
			n--;
			// 已经复制了n个 要停止了
			if (n == 0)
			{
				*dest++ = '\0';	// 防止n小于src长度,最后结尾无'\0';
				break;
			}
		}
	}
	while (n>0)
	{
		*dest++ = '\0';
		n--;
	}
	
}

int main()
{
	char s1[10] = "abba";
	char s2[10] = "";
	char s3[10] = "";
	char s4[10] = "";
	my_strcnpy(s2, s1, 4);
	my_strcnpy(s3, s1, 2);
	my_strcnpy(s4, s1, 8);
	printf("%s\n", s1);
	printf("%s\n", s2);
	printf("%s\n", s3);
	printf("%s\n", s4);
	return 0;
}

s2、s3、s4:分别对应长度正好、长度短缺、长度大于情况,且运行均正常

请添加图片描述

3.strncat:长度受限的字符串追加函数

  • strcat():字符串追加函数
  1. 把src字符串追加给dest。
  2. 寻找dest的’\0’,这是末位。把’\0’开始的值换为dest。
  3. 不必考虑给src末位再加’\0’,因为挨个复制dest,dest末位有’\0’。
  4. 与cmp不同在先循环找dest末位。
void my_strncat(char* dest, char* src)
{
	assert(dest && src);	// dest和src要同时存在
	// 1. 先找目标的\0
	while (*dest)
	{
		dest++;
	}
	while (*dest++ = *src++)
	{
		;
	}
}
  • strncat()的思路:受限的字符串追加函数
  1. 给字符串s1后追加s2的n个.。有两种情况,n大于s2,n小于等于s2。
  2. n>len(s2),则把s2都加上,如果s2没有了,剩余都补’\0’;
  3. 如果n<len(s2),则取n个s2值,给src
  4. n小于的s2长度的情况,追加n个,都别忘了最后给s1最后加’\0’;
char* my_strncat(char* dest, char* src, int sz)
{
	assert(dest && src);	// dest和src要同时存在
	// 1. 先找目标的\0
	char* res = dest;
	while (*dest)
	{
		dest++;
	}
	// 现在dest是\n sz大于src的长度
	while (*src)
	{
		if (sz > 0)
		{
			*dest++ = *src++;
			sz--;
		}
		else {
			return res;
		}
	}
	// src不存在,但是要追加sz个,就给它补充0
	if (sz == 0)
	{
		return res;
	}
		while (sz)
		{
			*dest++ = '\0';
			sz--;
		}
	*dest++ = '\0';
	return res;
}

int main()
{
	// 测试 my_strncat
	char src[6] = "bbbbb";
	char dest[25] = "aaaa";
	printf("长度为:%d\n", strlen(src));
	my_strncat(dest, src, 5);
	printf("111");
	return 0;
}

运行测试:

  1. 追加长度n大于src长度时正常:
    请添加图片描述

  2. n小于src时正常:

请添加图片描述
3. 等于src正常:

请添加图片描述

4. strncmp:长度受限的字符串比较函数

  • strcmp()的思路:
  1. 比较字符串大小需要一位位比较,且每位只有两种情况:当前等或不等。
  2. 相等比较复杂:如果等,则看是否其中之一为’\0’,为空则返回0,因为说明两个一直相等,然后往后挪动指针后也,现在都已处在了结尾或者也或许一开始比就是两个空字符串。如果当前不是’\0’,就往后挪动指针:s1++,s2++,继续比较后面。
  3. 如果当前位不等,没有进循环,直接返回*s1-*s2;负数说明前面小,反之前面大。
int my_strncmp(char* s1, char*s2)
{
	assert(s1 && s2);
	while (*s1 == *s2)
	{
		if (*s1 == '\0')
		{
			return 0;
		}
		s1++;
		s2++;
	}
	return *s1 - *s2;
}
  • strncmp思路:
  1. 在strcmp基础上多了一个n的限制,即在n个字符之内,判断出它俩谁大小。
  2. 只要在s1和s2相同部分做限定,因为如果在小于n的地方,两个字符串不同,就会出while循环。不必考虑。
  3. 只需要注意while相等时,已经比了n位,就退出并且说明n字符内,两个串相等。
  • 运行结果:
    请添加图片描述

请添加图片描述
请添加图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值