sprintf的原型如下

int sprintf(char *str, const char &format, ...);

sprintf是字符串格式化命令,主要功能是把格式化的数据写入字符串str中,返回值为写入str的字节数,结束字符‘\0’不计入内。其中, str是指要写入的缓冲区,format控制要写入str中数据的格式,例如%s、%d、%x等。

snprintf的原型:

int snprintf(char *str, size_t size, const char *format, ...);

snprintf是字符串格式化命令,主要功能是把格式化的数据写入字符串str中,最多写size个字节,包括自动添加在字符串末尾处的结束字符‘\0’;返回值为写入str的字节数,包括结束字符‘\0’。

sprintf与snprintf将通过下列小程序说明:

#include <stdio.h>

#include <string.h>

int main()

{

char name1[6] = {'\0'};

char name2[6] = {'\0'};

int size1 = sprintf(name1, "%s", "Arthur");

printf("name1:%s, size1:%d\n", name1, size1);

int size2 = snprintf(name2, strlen("Arthur"), "%s", "Arthur");

printf("name2:%s, size2:%d\n", name2, size2);

return 0;

}

程序输出为:

name1:Arthur size1:6

name2:Arthu, size2:6

为什么name2输出为“Arthu”呢?因为最多写入6个字节,且包括结束字符‘\0’,所以在将"Arthur"写入name2时,结束字符‘\0’将替换字符r,故name2为“Arthu”。

该程序有没有问题呢?

有,该程序越界了,但编译运行时不会报错,很难发现。系统为变量name1分配的6个字节的空间,使用sprintf向name1以%s的格式写入数据时,在数组name1起始的位置写入“Arthur”后,将在和name1相邻的第一个字节中写入结束字符‘\0’,而该字节不是分配给name1的,如果name1相邻的内存中有数据,它将被结束字符‘\0’覆盖,造成异常,因此尽量使用更为安全的snprintf函数,而不是sprintf。

对于snprintf使用时要注意把格式化的数据写入字符串str中,最多只能写size个字节,包括自动添加在字符串末尾处的结束字符‘\0’。例如想要将数组a中的内容以%02x的格式写入到buf中,如下

#include <stdio.h>

int main()

{

char a[20] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9,

0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13};

char buf[20*2] = {0};

for(int i = 0; i < 20; ++i) {

snprintf(&buf[i*2], 2, "%02x", a[i]);

}

printf("buf:%s\n", buf);

return 0;

}

我们期望为buf:000102030405060708090a0b0c0d0e0f10111213,实际输出却是

buf:0

为什么呢?因为snprintf将每个a[i]以 "%02x"格式写入buf[i]时,每个a[i]在buf指向的空间里占两个字节,第二个字节将被结束字符‘\0’替代,因此buf中的内容为0’\0’0’\0’0’\0’0’\0’0’\0’0’\0’0’\0’0’\0’0’\0’0’\0’0’\0’0’\0’0’\0’0’\0’0’\0’0’\0’1’\0’1’\0’1’\0’1’\0’。

程序的正确写法如下:

#include <stdio.h>

int main()

{

char a[20] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9,

0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13};

char buf[20*2 + 1] = {0};

for(int i = 0; i < 20; ++i) {

snprintf(&buf[i*2], 3, "%02x", a[i]);

}

printf("buf:%s\n", buf);

return 0;

}

sprintf与snprintf区别相关推荐

  1. sprintf 和 snprintf区别

    sprintf 和snprintf 函数区别 sprintf 函数定义见: https://cplusplus.com/reference/cstdio/sprintf/ snprintf 函数定义见 ...

  2. 三个打印函数printf()/sprintf()/snprintf()区别

    先贴上其函数原型 printf( const char *format, ...)    格式化输出字符串,默认输出到终端-----stdout sprintf(char *dest, const c ...

  3. 【字符串处理函数】sprintf与snprintf

    sprintf与snprintf 1.功能 1.1 sprintf 1.2 snprintf 2.函数说明 2.1 sprintf 2.1.1 函数原型 2.1.2 参数列表: 2.1.3 返回值: ...

  4. 关于sprintf和snprintf的比较

    #include <stdio.h> #include <string.h>typedef unsigned char uchar;#define BUF_SIZE 10 // ...

  5. C 字符串函数 sprintf()、snprintf() 详解

    一.sprintf() 函数详解 在将各种类型的数据构造成字符串时,sprintf 的强大功能很少会让你失望. 由于 sprintf 跟 printf 在用法上几乎一样,只是打印的目的地不同而已,前者 ...

  6. C库函数:scanf、fscanf、printf、fprintf、sprintf、 snprintf

    1. scanf 函数原型 int scanf(const char *format, ...);  功能:从标准输入 stdin 读取格式化输入. 2.fscanf 函数原型 int fscanf( ...

  7. sprintf,sscanf,snprintf

    sprintf:将格式化的数据写入字符串,第一个参数是缓冲区buf.成功返回写字符的总数,失败返回一个负数 1.最简单用法: char str[20]; sprintf(str,"%d&qu ...

  8. [C] 库函数 sprintf() 和 snprintf()

    sprintf 发送格式化输出到 str 所指向的字符串 int sprintf(char *str, const char *format, ...) 实例: char filename[50]; ...

  9. [转]PHP echo, print, printf, sprintf函数的区别和使用

    1. echo函数: 输出函数,是命令,不能返回值.echo后面可以跟很多个参数,之间用分号隔开,如: echo $myvar1; echo 1,2,$myvar,"<b>bol ...

最新文章

  1. [代码笔记]VUE路由根据返回状态判断添加响应拦截器
  2. 恢复Reflector反编译后资源文件的办法
  3. Relu神经网络输出预测全为0或1,对所有输入样本的预测概率也相同
  4. python连等号_Python比较2列表和2元组用等号
  5. 数字孪生数据中心机房,智能 IDC 高阶运维
  6. 凝心聚力 数字未来 | 企企通出席石家庄医药行业数字化转型沙龙
  7. html有形状导航栏制作,div css制作导航栏
  8. 移动节点的间接路由方式
  9. arcgis for js4.x自定义图例位置添加到地图并导出
  10. 介于上海与江苏的地铁小户型
  11. git tag 打标签(我看过最透彻的文章)
  12. (李嘉诚)教你投资理财
  13. Python将两个列表合并为一个字典
  14. vue 梯形百分比占比图
  15. 滴滴 美洽 架构师 李令辉
  16. 西瓜书第二章阅读笔记
  17. 行业分析-单机游戏市场现状及未来发展趋势
  18. 机房计算机怎么查找192文档,计算机专业机房简介
  19. 探索如何在武汉链(基于ETH)的一个合约中实现同质化与非同质化功能
  20. SpringBoot框架技术总结(五)

热门文章

  1. 20221125使用PR2023自动识别obs-studio录屏生成的MKV视频的字幕
  2. Handler 简介
  3. 黑客攻防技术宝典(七)
  4. CF1364D Ehab‘s Last Corollary
  5. Solr DIH使用说明
  6. texstudio: 无法启动buildview:Xelate: xelatex.exe -synctex=1 -interacion=nonstopmode
  7. git 创建远程新分支
  8. UNIX下PageDown健如何捕捉
  9. java基础知识精华总结集合
  10. 解决VMware虚拟机界面太小的问题