snprintf和strncpy对比

有关snprintf返回值更多信息,请参考:http://bbs.hadoopor.com/thread-1185-1-1.html

snprintf MAN手册:
The functions snprintf() and vsnprintf()  do  not  write  more  than  size  bytes  (including  the trailing '\0')
这句话表示snprintf总是会将'\0'写入。

strncpy MAN手册:
The  strncpy() function is similar, except that not more than n bytes of src are copied. Thus, if there is no null  byte among the first n bytes of src, the result will not be null-terminated.
这句话表明如果源字符串比指定的目标长度大,则不会写入'\0',也就是strncpy总是严格尊守指定大小,绝不越雷池半步,也绝不做份外的工作,可以理解成死板。

从上可以看出,snprintf和strncpy用法稍有不同,分别如下:
char dst[X];
char src[Z];
snprintf(dst, sizeof(dst), "%s", src);

strncpy(dst, src, sizeof(dst)-1);
dst[sizeof(dst)-1] = '\0';

测试代码:
int main()
{
    char dest1[3];
    char dest2[3];
    char src[] = "0123456789";

    printf("src[2]=%d,%c\n", src[2], src[2]);

    strncpy(dest1, src, sizeof(dest1)-1);
    printf("dest1[2]=%d,%c\n", dest1[2],dest1[2]);  // dest1[2]是一个未初始化的随机值

    snprintf(dest2, sizeof(dest2), "%s", src);
    printf("dest2[2]=%d,%c\n", dest2[2],dest2[2]); // dest2[2]总是一个C字符串结尾符'\0'

    return 0;
}

也就是strncpy总是拷贝指定大小的字节数,绝不会多做,所以不会自动加结尾符'\0',除非指定大小的字节数范围内的src已经包含了结尾符'\0'。
但snprintf总是只拷贝指定大小减1后的字节数,然后再自动加上结尾符'\0'。因此对于上述strncpy的用法,还应当加上:
dest1[sizeof(dest1)-1] = '\0';
这个时候就正常了,当然也可以:
  1. strncpy(dest1, src, sizeof(dest1)); // 前sizeof(dest1)个字节,src和dest1将完全相同
  2. dest1[sizeof(dest1)-1] = '\0'; // 将第sizeof(dest1)-1个字节处置为结尾符'\0'

复制代码 所以对于strncpy是否需要sizeof()-1,也并非必要的,完全可以只sizeof(),但一定得再加上结尾符'\0'。 从上也可以看出,不管是strncpy还是snprintf,它们都会尊重sizeof(),都不会向dest拷贝超过sizeof()大小的字节数。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏用户2442861的专栏

数据库系统——B+树索引

http://blog.csdn.net/cjfeii/article/details/10858721

4061
来自专栏程序员互动联盟

【答疑释惑】C语言里面结构体大小统计方法

之前说过一个关于结构体在内存中所占字节数的问题,我们知道结构体长度的计算并不是所有成员长度的相加,而是因为编译器优化会对其进行对齐,这样会优化访问速度等。 那...

3127
来自专栏前端儿

队花的烦恼一

ACM队的队花C小+经常抱怨:“C语言中的格式输出中有十六、十、八进制输出,然而却没有二进制输出,哎,真遗憾!谁能帮我写一个程序实现输入一个十进制数n,输出它的...

792
来自专栏debugeeker的专栏

《coredump问题原理探究》Linux x86版5.7节C风格数据结构内存布局之结构体数组

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xuzhina/article/detai...

721
来自专栏mathor

LeetCode329. 矩阵中的最长递增路径

 dfs,主函数中枚举起点,然后dfs函数中枚举四个方向进行移动,但是光dfs还不够,因为我们发现存在很多冗余,所以这是一道dfs+dp的问题,resul...

1321
来自专栏闻道于事

Java异常处理中的恢复模型

2714
来自专栏开发与安全

从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)

首先重新回顾一下关于类/对象大小的计算原则: 类大小计算遵循结构体对齐原则 第一个数据成员放在offset为0的位置 其它成员对齐至min(sizeof(me...

2220
来自专栏灯塔大数据

每周学点大数据 | No.23 外排序(二)

No.23期 外排序(二) Mr. 王:接下来我们用一个例子对磁盘归并排序进行说明。先来约定讨论的参数:N=24,M=8,B=2。 小可:嗯,一共有2...

3386
来自专栏夏时

PHP 正则表达式后面接的/isU, /is, /s含义

1632
来自专栏java思维导图

8张图理解Java,一图胜千言

一图胜千言,下面图解均来自Program Creek 网站。如果图解没有阐明问题,那么你可以借助它的标题来一窥究竟。 1、字符串不变性 下面这张图展示了这段代码...

2433

扫码关注云+社区

领取腾讯云代金券