字符串函数介绍与模拟实现

C语言库中有很多函数,其中字符串函数是比较常用的一块,需要我们去掌握。

目录

1. strlen(求字符串长度)

1.1 strlen 模拟实现

2. strcpy(复制字符串)

2.1 strncpy函数

2.2 模拟实现strcpy

3. strcat (追加字符)

3.1 strncat 函数

3.2 模拟实现strcat

4. strcmp(比较两个字符串内容)

4.1 strncmp函数

4.2 模拟实现strcmp

5. strstr (返回str1出现在str2位置处第一次的指针)

5.1 模拟实现strstr

6. strtok(分割字符串)


1. strlen(求字符串长度)

这个函数就是求一个字符串的长度。

注意它是不算'\0'的,即以'\0'为结束标志,计算其之前的字符串长度,但不能没有'\0'.

让我们来一个有趣的例子:

int main()
{
	if (strlen("abc") - strlen("abcdef"))
		printf("hehe");
	else
		printf("haha");
	return 0;
}

以上的代码乍一眼看是3 - 6 = -3,应该输出haha

但是strlen函数返回的是无符号整型,所以-3被看作无符号整数,应该是一个大于0的数。 

1.1 strlen 模拟实现

那么这个函数自己来写应该怎样实现呢?

模拟实现需要考虑到所有情况

所以 const 防止改变字符串与 assert 防止传入空指针不可少。

size_t my_strlen(const char* a)
{
	assert(a);
	int count = 0;
	while (*a)
	{
		count++;
		a++;
	}
	return count;
}

  

2. strcpy(复制字符串)

这个函数用于把一个字符串内容赋给另一个字符串内,如果目的字符串有内容,直接覆盖。

注意点:strcpy复制字符串从arr2arr1

被复制的字符串一定要带'\0',因为这个是结束标志

目标空间也要足够大且可变(可变:用数组写,而非指针卡死)

int main()
{
	char arr1[] = "xxxxxxxxxxxxxxx";
	//char *p = "xxx";//不可变且空间小
	char arr2[] = "abcd\0efg";
	strcpy(arr1, arr2);
	printf("%s", arr1);
	return 0;
}

2.1 strncpy函数

这个函数是不是很相像?由于strcpy 直接将一个字符串完全复制过去,

那么有没有一个函数能只复制一部分呢?此函数就是充当这个作用的。

它将 num 个字符从源字符串中取出,放入目的字符串。

int main()
{
	char a[] = "abcde";
	char b[] = "abc";
	strncpy(a, b, 6);
	printf("%s", a);
	return 0;
}

 如果遇到源字符串不够的情况,会自动补0.

2.2 模拟实现strcpy

char* my_strcpy(char* a1, const char* a2)//原指针被修改,不加const
{
	assert(a1 && a2);
	char* ret = a1;
	while (*a1++ = *a2++)
	{
		;
	}
	return ret;
}

来解释一下这个写法(*a1++ = *a2++ ):

先把a2赋给a1,然后各自++。当a2为0时,这个表达式值为0,就退出循环。

因为值放在地址内,所以a1的地址给ret存好后,最后返回ret的地址就是返回a1的值.

  

3. strcat (追加字符)

传入两个字符串,将后一个字符串追加到前一个字符串上。 

源字符串必须要有 '\0' 作为结束标志,且目标字符串足够大且可变。(提前定义目标数组大小)

如果需要自己给自己追加,那么就使用这个函数。

3.1 strncat 函数

就是将源字符串 num 个字符追加到目标字符串上,如下图:

 

3.2 模拟实现strcat

char* my_strcat(char* a, const char* b)
{
	assert(a && b);
	char* p = a;

	//先找到a字符串为'\0'的位置
	while (*a)
	{
		a++;
	}

	while (*a++ = *b++)
	{
		;
	}
	return p;
}

4. strcmp(比较两个字符串内容)

 传入两个字符串,比较两个字符串。

str1 > str2 返回正数; = 返回0; < 返回负数

那么是怎么比较的呢?

记住是比较不相同的那个字符大小跟长度没有一点关系

如图就是比较 'e' 和 'q' 的字符大小,明显 'q' 更大,所以返回 -1.

4.1 strncmp函数

和strncpy相似,就是将两个字符串前num个字符比较,规则同 strcmp 函数 。

4.2 模拟实现strcmp

int my_strcmp(const char* a, const char* b)
{
	assert(a && b);
	while (*a == *b)
	{
		if (*b == '\0')
			return 0;
		a++;
		b++;
	}
	/*if (*a > *b)
		return 1;
	if (*a < *b)
		return -1;*/
	return *a - *b;//这样一步到位
}

   

5. strstr (返回str1出现在str2位置处第一次的指针)

就是返回b字符串在a中第一次出现的位置的指针,如下就会打印 am a student.

如果没有找到就返回空指针

int main()
{
	char a[] = "I am a student.";
	char b[] = "am";
	printf("%s", strstr(a, b));
	return 0;
}

5.1 模拟实现strstr

char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	char* s1;
	char* s2;
	char* cp = str1;
	
	if (*str2 == '\0')//如果传入了""
		return str1;

	while (*cp)
	{
		s1 = cp;
		s2 = str2;
		while (*s1 == *s2 && *s1 && *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return cp;
		}
		cp++;
	}
	return NULL;
}

   

6. strtok(分割字符串)

这个函数能以我们所需分割字符串,sep是分割的标志,str是被分割的字符串。

下面来一个例子:

int main()
{
	char a[] = "123@qq.com";
	char b[] = "@.";
	printf("%s\n", strtok(a, b));//分割了123
	printf("%s\n", strtok(NULL, b));//分割了qq
	printf("%s\n", strtok(NULL, b));//分割了com
	return 0;
}

第一次分割完,之后这个函数会记住分割的位置,把目标函数的分割标志变为'\0'

所以这个函数会修改字符串,要小心使用。

下次使用只需要传入空指针,这是这个函数的重点。

我们也可以使用循环来表达它的结果:

int main()
{
    char *p = "666@qq.com";
    const char* sep = ".@";
    char arr[30];
    char *str = NULL;
    strcpy(arr, p);//将数据拷贝一份,处理arr数组的内容
    for(str=strtok(arr, sep); str != NULL; str=strtok(NULL, sep))
    {
        printf("%s\n", str);
    }
}

感谢你能看到这,如有帮助给个赞呗。

  • 18
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丶chuchu丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值