strcpy/strncpy,sprintf/snprintf,strncpy/snprintf的区别


下面的测试基于VS2019,测试过程中会报错并提示使用诸如strcpy_s建议,只需要屏蔽报错强制编译执行即可——在代码开头加上:

#pragma warning(disable:4996)//4996为提示的错误码

1.strcpy/strncpy

char *strcpy(char *dest, const char *src);
char * strncpy(char *dest, const char *src, size_t n);
  • dest 为目标字符串指针,src 为源字符串指针。
  • 成功执行后返回目标数组指针 dest。
  • strcpy() 把src所指的字符串复制到dest 所指的数组中,返回指向 dest 字符串的起始地址。
  • strncpy()会将字符串src前n个字符拷贝到字符串dest。
  • srrncpy()不会自动添加’\0’
  1. 测试1:strcpy 正常使用,空间足够无越界
    char dest[20];
    char src[12] = "Hello-World";
    strcpy(dest, src);
    printf("dest:%s", dest);
    //输出——dest:Hello-World
  1. 测试2:strcpy dest空间小于src空间
    char dest[10];//小于src空间
    char src[12] = "Hello-World";
    strcpy(dest, src);
    printf("dest:%s\n", dest);
    //输出——dest:Hello-World
    //引发异常:Run-Time Check Failure #2 - Stack around the variable 'dest' was corrupted.
    //即:运行时检查失败 #2 - 变量“dest”周围的堆栈已损坏。
  1. 测试3:strncpy 参数n不超过dest的大小
    char dest[10];//小于src空间
    char src[12] = "Hello-World";
    strncpy(dest, src,9);//参数n=9并没有超出空间限制
    printf("dest:%s", dest);
    //输出——dest:Hello-Wor烫烫烫虥鍨8?s0

目标字符串后面有乱码
原因: print以’\0’标识结尾。而strncpy并不会在拷贝后自动添加’\0’
4. 测试4:手动在dest末尾添加结束符‘\0’

    char dest[10];
    char src[12] = "Hello-World";
    strncpy(dest, src,9);
    dest[9] = '\0';
    printf("dest:%s", dest);
    //输出——dest:Hello-Wor

正常执行

2.sprintf/snprintf

printf 将输出在命令行显示
sprintf/snprintf 将输出赋值给字符串,其余的基本使用方式和printf一致

int sprintf(char *dest, const char *src, ...);
int snprintf(char *dest, size_t n, const char *src, ...);
  • dest 为目标字符串指针,src 为源字符串指针。
  • 返回值为被拷贝的字符串的长度,即src的长度
  • 参数n算上了’\n’,因此实际只拷贝了n-1个字符
  1. 测试1:sprintf正常使用,空间足够无越界
    char dest[20];
    char src[12] = "Hello-World";
    int ret=sprintf(dest, src);
    printf("dest:%s\n ret=%d\n", dest,ret);
    //输出——dest:Hello-World
	//     ret=11
  1. 测试2:sprintf dest空间小于src空间
    char dest[10];//小于src的空间
    char src[12] = "Hello-World";
    int ret=sprintf(dest, src);
    printf("dest:%s\nret=%d\n", dest,ret);
    //输出——dest:Hello-World
	//     ret=11
	//同时引发异常:Run-Time Check Failure #2 - Stack around the variable 'dest' was corrupted.
    //即:运行时检查失败 #2 - 变量“dest”周围的堆栈已损坏。
  1. 测试3:snprintf 参数n不超过dest的大小
    char dest[10];
    char src[12] = "Hello-World";
    int ret=snprintf(dest,7,src);
    printf("dest:%s\nret=%d\n", dest,ret);
    printf("dest length=%d\n", strlen(dest));
    //输出——
    //dest:Hello-
    //ret=11
    //dest length=6

可以看出dest的长度 比参数n少1

3.strncpy/snprintf

从上面strcpy/strncpy,sprintf/snprintf两个测试3可以看出strncpy/snprintf的区别如下:

  1. 返回值:strncpy是返回目标dest指针,snprintf返回的是被拷贝的字符数,即src的字符数(注意这里不是成功拷贝的字符数)
  2. 参数n:strncpy是实际拷贝的字符数,snprintf实际拷贝了n-1个字符
  3. snprintf会自动在dest末尾加上’\0’字符,这样在输出的时候不会导致越界;而strncpy要想正常输出,需要手动在末尾添加’\0’字符
  4. n的传递:使用sizeof(dest)更安全方便。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值