一、strncpy
char *strncpy(char* dest,const char* src,const size_t n);
#include <stdio.h>
#include <string.h>
int main()
{
char dest[20];
memset(dest,0,sizeof(dest));
strncpy(dest,"ssc_zcys",5);
printf("1=%s\n",dest);
//memset(dest,0,sizeof(dest));
strcpy(dest,"ssc_zcys");
printf("2=%s\n",dest);
//memset(dest,0,sizeof(dest));
strncpy(dest,"ssc_zcys",5); //strncpy函数的缺陷
printf("3=%s\n",dest);
//memset(dest,0,sizeof(dest));
strncpy(dest,"ssc",5);
printf("4=%s\n",dest);
}
输出结果:
二、函数缺陷
-
如果src字符串长度小于n,拷贝完字符串后,不会在dest后追加0(结尾符)
-
如果src的长度大于等于n,就截取src的前n个字符,不会在dest后追加0(结尾符)
三、解决方法:
字符串在每次使用前初始化为0或者重写strncpy函数
1、使用前初始化为0
memset(dest,0,sizeof(dest));
2、重写strncpy函数
函数声明:
char *STRNCPY(char* dest, const char* src, size_t n);
函数实现:
/*
* 解决缺陷:
* 如果src字符串长度小于n,则拷贝完字符串之后,在dest后追加0(结尾符),直到n个
* 如果src字符串长度大于等于n,就截取src的前n个字符,在dest后追加0(结尾符)
*/
char *STRNCPY(char* dest, const char* src, size_t n)
{
int len=0;
//计算应该复制多少字节
if(strlen(src) > n) len=n;
else len=strlen(src);
int i=0;
for(i=0;i<len;i++)
{
dest[i]=src[i];
}
dest[len]=0;
return dest;
}
四、测试
将重写的函数和声明加入自己的函数库 _public.c 和 _public.h
Test1
//包含头文件_public.h
#include "_public.h"
#include <stdio.h>
#include <string.h>
int main()
{
char str[32];
STRNCPY(str,"ssc_zcys",13); //src_len<n
printf("1-str=%10s str_len=%d \n",str, strlen(str));
STRNCPY(str,"ssc_zcys",8); //src_len=n
printf("2-str=%10s str_len=%d \n",str, strlen(str));
STRNCPY(str,"ssc_zcys",6); //src_len>n
printf("3-str=%10s str_len=%d \n",str, strlen(str));
return 0;
}
输出:
Test2
//包含头文件_public.h
#include "_public.h"
#include <stdio.h>
#include <string.h>
int main()
{
char dest[20];
memset(dest,0,sizeof(dest));
//调用重写的STRNCPY函数
STRNCPY(dest,"ssc_zcys",5);
printf("1=%s\n",dest);
//memset(dest,0,sizeof(dest));
strcpy(dest,"ssc_zcys");
printf("2=%s\n",dest);
//memset(dest,0,sizeof(dest));
STRNCPY(dest,"ssc_zcys",5); //解决strncpy函数的缺陷
printf("3=%s\n",dest);
//memset(dest,0,sizeof(dest));
STRNCPY(dest,"ssc",5);
printf("4=%s\n",dest);
return 0;
}
输出: