strncpy、strncat、strncmp函数的使用说明和模拟实现

在前面的文章中,我已经介绍了长度不受限制的字符串函数。今天我来介绍几个长度受限制的字符串函数,并且模拟实现这些长度受限制的字符串函数。





strncpy函数

strncpy函数也是一个拷贝函数,但是与strcpy函数有所不同,strncpy函数是从源字符串拷贝num个字符到目标字符串,num是strncpy函数的一个参数,当源字符串的字符数目小于num时,在拷贝完源字符串后,会在目标字符串中追加0,直到达到num的数目。
请添加图片描述
由msdn查询可以得知,strncpy函数的返回值和参数是:
char* strncpy(char* destination,const char* source,size_t num)。注意我们只关注返回类型和参数的类型,参数的名字不管。

接着,继续往下查询strncpy函数的返回值。
请添加图片描述
由msdn对strncpy的返回值的介绍可知,strncpy函数返回目标字符串的地址。

接下来,我来举一个strncpy函数的使用例子。

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[20] = "abcdef";
	char arr2[] = "xxxxxx";
    printf("%s\n",strncpy(arr1,arr2,5));
    return 0;
}

请添加图片描述
由运行结果可以知道,strncpy函数确实从源字符串拷贝num个字符到目标字符串。

接下来,我来验证一下strncpy函数的拷贝过程中,源字符串达不到num个字符,那么就会在拷贝完源字符串后,在目标字符串后面补0,直到达到num个字符。

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[20] = "abcdefhij";
	char arr2[] = "xxxx";
    printf("%s\n",strncpy(arr1,arr2,8));
    return 0;
}

在strncpy函数拷贝前,arr1的内容如下:
请添加图片描述

在strncpy函数拷贝后,arr1的内容如下:
请添加图片描述
在该程序中,arr2中有4个字符,而strncpy函数却要从arr2中拷贝8个字符到arr1,按照源字符串不足拷贝时,要在源字符串拷贝后补0,那么就要补4个0。由图片可以得知,arr1确实被覆盖了arr1的内容和4个0。

接下来,我来实现strncpy函数的模拟实现。

#include<stdio.h>
#include<assert.h>
#include<string.h>
char* my_strncpy(char* dest,const char* src,size_t len)
{
	char* ret = dest;
    int offset = 0;
	assert(dest != NULL);
	assert(src != NULL);
	if(strlen(src) < len)
	{
	    offset = len - strlen(src);
		len = strlen(src);
	}
	while(len)
	{
	    *dest++ = *src++;
		len--;
	}
	while(offset)
	{
	    *dest++ = '\0';
		offset--;
	}
	return ret;
}
int main()
{
	char arr1[20] = "abcdef";
	char arr2[] = "xxxx";
	my_strncpy(arr1,arr2,3);
	printf("%s\n",arr1);
    return 0;
}

请添加图片描述
由图片可以知道,该模拟实现函数可以满足strncpy函数的要求。



strncat函数

strncat函数与strcat函数功能差不多相同,唯一有区别的是strncat函数是追加count个字符(count是strncat函数的参数),而strcat是将整个字符数组追加到另一个字符数组。

请添加图片描述
由msdn查询可知,strncat函数的返回类型和参数类型是:
char* strncat(char* dest,const char* src,size_t num),注意,我们只关注返回类型和参数类型,不关注参数名字。
请添加图片描述
在msdn继续查询可以得知,strncat函数的返回值是目标字符串的地址。(注意这里是返回值,跟上面的返回类型有所不同)

现在,我来举一个strncat函数的使用例子。

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[20] = "abcdef"; 
	char arr2[] = "xyz";
	printf("%s\n",strncat(arr1,arr2,2));
    return 0;
}

请添加图片描述
接下来,我来写一个小程序,观察一下strncat函数的更多的细节。

#include<string.h>
int main()
{
	char arr1[20] = "abcdef\0qqqqqqqqqqqq";
	char arr2[] = "xyz";
	strncat(arr1,arr2,2);
    return 0;
}

这是arr1开始时存储的内容:请添加图片描述

这是arr1数组被追加时的内容:

请添加图片描述

对比一下arr1被拷贝前和被拷贝后的变化可以发现,strncat还是从’\0’开始覆盖,并且覆盖完后对应的几个字符后,开始在后面加个’\0’。

在上一篇文章中,我已经验证过strcat函数不能用在字符串自己给自己追加,那么与strcat函数功能差不多的是strncat函数,能不能用在字符串自己给自己追加呢?

我用小程序来验证一下。

#include<string.h>
int main()
{
	char arr1[20] = "abc";
	strncat(arr1,arr1,3);
    return 0;
}

arr1被追加字符前:
请添加图片描述

这是arr1被追加后:
请添加图片描述

由调试过程中的观察可以得知,strncat的确实现了字符自己给自己追加,我来分析一下成功的原因所在。

在前面文章提到的strcat函数不能用在字符串自己给自己追加的原因是’\0’被覆盖掉,而strcat函数是以从源字符串拷贝到’\0’去到目标字符串作为停止条件,而’\0’却在拷贝的过程中被覆盖掉,那么strcat函数就会持续的拷贝,进入到死循环拷贝。

与strcat函数不同的是,strncat函数是以拷贝完想要拷贝的字符字数(即给strncat函数传参的数字)作为结束标志,并且在拷贝完成的目标字符串后面再添加个’\0’,注意的是,这个’\0’不是从源字符串中拷贝过来的,strncat函数自己添加的,那么,即使arr1中的’\0’早早的就被覆盖掉,也不会影响strncat函数的正常运作。

接下来,我来模拟实现strncat函数。

#include<stdio.h>
#include<assert.h>
char* my_strncat(char* dest,const char* src,size_t num)
{
    char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while(*dest != '\0')        //找到'\0'的位置
	{
	    dest++;
	}
	while(num--)                //开始往目标字符串追加字符
	{
	    *dest++ = *src++;
	}
	*dest = '\0';               //最后覆盖'\0'
	return ret;
}
int main()
{
	char arr1[20] = "abcdef";
	char arr2[] = "abcdef";
	printf("%s\n",my_strncat(arr1,arr2,5));
    return 0;
}

请添加图片描述
由运行结果可以发现该模拟实现strncat函数确实满足了我们的要求。



strncmp函数

strncmp函数与strcmp函数都是字符串比较函数,有区别的是strncmp只是比较调用该函数时传参的num个字符,那么我依然来介绍一下该函数的返回类型和参数类型,还有返回值吧。

请添加图片描述
在msdn查询可以得知,strncmp函数的参数类型和返回类型是:int strncmp(const char* str1,const char* str2,size_t num),与strcmp函数参数类型和返回类型相比,只是多了个参数。

接下来,我来介绍一下该函数的返回值。
请添加图片描述
1.第一个字符串小于第二个字符串,返回小于0的数字。
2.第一个字符串等于第二个字符串,返回等于0的数字。
3.第一个字符串大于第二个字符串,返回大于0的数字。

接下来,我来举一个strncmp函数的使用例子。

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[20] = "abcdefghi";
	char arr2[] = "abcdef";
	printf("%d\n",strncmp(arr1,arr2,6));
	return 0;
}

运行结果如下:
请添加图片描述
观察arr1和arr2的字符数组可以得知两者根本不一样,但是我们只想比较前6个字符是否不一样,所以就给strncmp函数传参传6,结果返回了0,也就是前6个元素是一样的。

接下来,我来模拟实现strncmp函数。

#include<stdio.h>
#include<assert.h>
int my_strncmp(const char* str1,const char* str2,size_t num)
{
	assert(str1 != NULL);
	assert(str2 != NULL);
    while(num--)
	{
	    if(*str1 == *str2)
		{
		    str1++;
			str2++;
		}
		else
		{
		    if(*str1 > *str2)
			{
				return 1;
			}
			else
			{
			    return -1;
			}
		}
	}
	return 0;
}
int main()
{
    char arr1[] = "abcdef"; 
	char arr2[] = "abcdefghijk";
	printf("%d\n",my_strncmp(arr1,arr2,6));
	return 0;
}

运行结果如下:
请添加图片描述
该模拟实现strncmp函数确实满足了我们的要求。

今天,我对于长度受限制的字符串函数已经介绍完了,而字符串函数的还多着,关注点一点,下期继续学字符串函数。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
strncpy()和strncpy_off()是用于字符串拷贝的函数。在示例代码中,substr_cpy()和substr_cpy_off()函数分别用来将字符串s2的一部分拷贝到s1中,并指定拷贝的起始位置和长度。例如,substr_cpy(s1, s2, 0, 6, elcount(s1))表示将s2中从索引0开始的6个字符拷贝到s1中,结果为"Vector"。substr_cpy_off(s2, 7, s1, 4, -1, elcount(s2))表示将s1中从索引4开始的-1个字符拷贝到s2中的索引7位置上,结果为"Vector CAPL"。而mbsubstr_cpy()和mbsubstr_cpy_off()函数与substr_cpy()和substr_cpy_off()函数的功能类似,但是适用于多字节字符串。 另外,strncpy()是将一个字符串拷贝到另一个字符串中的函数。在示例代码中,strncpy(s, "Vector", 10)表示将字符串"Vector"拷贝到s中,结果为"Vector"。而strncat()是将一个字符串追加到另一个字符串的末尾的函数。示例代码中,strncat(s, " CANoe", 19)表示将字符串" CANoe"追加到s的末尾,结果为"Vector CANoe"。需要注意的是,strncpy()和strncat()都有一个参数用于限制拷贝或追加的最大长度。 所以,strncpy和capl之间并没有直接的关联。strncpy()和strncat()函数是用于字符串拷贝和追加的函数,而capl可能是另外一个函数或概念。如果您能提供更多关于capl的上下文信息,我将能够给出更准确的回答。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [CAPL内置的与String有关函数](https://blog.csdn.net/u013391094/article/details/130041416)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值