前言
在字符串函数(一)中主要分析的是不受长度限制的字符串函数,这些函数在使用时相对长度受限制的字符串函数而言是不安全的。那这篇文章主要讲述的是一些长度受限制的字符串函数。
一、为什么要有长度受限制的字符串函数
在使用字符串的时候,我们有时需要的只是字符串的一部分,这个时候使用长度不受限制的字符串函数用起来就会很麻烦,所以才有了长度受限制的字符串函数。
二、函数实现
1.strncpy()函数
char * strncpy ( char * destination, const char * source, size_t num );
strncpy()函数和strcpy()函数相比只多了一个函数参数,那就是要拷贝的元素个数。
char* my_strncpy(char* dest, const char* src, size_t num)
{
assert(dest && src);//因为用到了指针,所以先对指针进行断言。
char* start = dest;
while (num && ((*dest++ = *src++) != '\0'))//循环停止的条件有两个,一个是拷贝结束,第二个是源字符串已经拷贝完全,但还没有达到num个大小
num--;
if (num)
{ //源字符串已经拷贝完毕,但没达到num个元素大小的情况
while (--num)//先--,因为在源字符串拷贝完成后,没进入循环,num没有自减,所以控制这个循环的条件就是先对num进行自减
*dest++ = '\0';
}
return start;
}
对这个字符串函数进行模拟实现的时候,一开始犯了一个错误:
while(((*dest++ = *src++) != '\0') && num);
第一个循环的条件一开始我是这么写的,但在使用该函数的时候每次都多拷贝了一个字符,通过调试,我发现,当num自减为0的时候,按照我一开始的写法,还有一次赋值过程。但如果把num放在前面,就不会有这种操作,因为&&是从左向右结合的,所以会优先判断num,只要num为假,就不会再运行后面的赋值语句并判断。
2.strncat()函数
char * strncat ( char * destination, const char * source, size_t num );
注意strncat()函数和strcat()函数不同,strcat()函数追加字符串,会把源字符串的’\0’也追加进去,但strncat()函数不同,它在函数追加完毕后,需要视条件在末尾添上一个’\0’的。
char* my_strncat(char* dest, const char* src, size_t num)
{
assert(dest && src);
char* start = dest;
while (*dest++)//找到目标字符串'\0'的地址
;
dest--;//在找到'\0'的地址还自增了,所以要--
while (num--)
{
if ((*dest++ = *src++) == 0)//判断,源字符串是否被完全拷贝
return start;
}
*dest = '\0';//跳出循环,说明源字符串被拷贝了一部分,需要给目标字符串添加一个'\0'截止
return start;
}
3.strncmp()函数
int strncmp ( const char * str1, const char * str2, size_t num );
该函数的截止条件有三个,一是有一个字符串结束,二是出现不一样的字符,三是num个字符完全比较完毕。
int my_strncmp(const char* str1, const char* str2, size_t num)
{
assert(str1 && str2);
while (num--)
{
//出循环的条件
//1.num == 0;
//2.字符串str1,str2都结束,返回0
//3.字符不相等
if (*str1 == *str2)
{
if (*str1 == 0 || num == 0)
return 0;
str1++;
str2++;
}
else
{
break;
}
}
return *str1 - *str2;
}
总结
以上就是有关长度受限的字符串函数的模拟实现,与不受长度限制的字符串函数相比略有不同,在使用的时候,选择长度受限的字符串函数还是不受限的字符串函数,要看实际情况使用。