`
boisterous
  • 浏览: 62782 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类

asprintf

阅读更多
sprintf() 的整个介面长的样子的是:

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

  也就是在使用前,必须要先建立好一个字元阵列的空间,再用这个函式把内容填入,下面就是简单的例子:

  int tmp = 10;

  char cstr[20];

  sprintf( cstr, "%d * %d = %d", tmp, tmp, tmp * tmp );

  在这个例子里,cstr 最后的值,会是「10 * 10 = 100」,看起来好像很好?但是如果把 tmp 的值改成 10000 的话,cstr 则应该要变成「10000 * 10000 = 100000000」,但是由於这时候的字串所需长度为 26,而要写入的 cstr 的长度只有 20,所以就会造成 buffer overflow 的问题。

  像如果是以 Visual C++ 2006 来编译的话,如果程式里有用到 sprintf(),他在编译时就会显示一个警告讯息:

  warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead.

  而要怎麼避免 sprintf 的 buffer overflow 的问题呢?除了微软建议的 sprintf_s() 外,实际上在 C99 里, 也多了一个 snprinf() 是用来取代现有的 sprintf() 了~他的介面是:

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

  应该可以明显看得出来,snprinf() 这个函式比 sprintf() 多了一个参数 size;这个参数的用处,就是用来限制最大的写入资料量,可以用来避免 buffer overflow。以上面的例子来说,本来写:

  int tmp = 10000;

  char cstr[20];

  sprintf( cstr, "%d * %d = %d", tmp, tmp, tmp * tmp );

  的话,会产生 buffer overflow 的问题。而如果改成用 snprinf() 的话,就是变成:

  int tmp = 10000;

  char cstr[20];

  snprintf( cstr, sizeof( cstr ), "%d * %d = %d", tmp, tmp, tmp * tmp );

  这样一来,snprinf() 在把资料写到 cstr 时,最多就只会写入 20 个字元(cstr 的长度),而不会有 buffer overflow 的问题了~

  不过比较讨厌的是,MSVC 似乎并没有直接给这个函式,而是另外给了一个 _snprinf()…虽然功能和参数都大同小异,但是光函式名称不一样,就已经增加了些麻烦,更别说在行为模式上也有些不同了。而 _snprinf() 和 snprintf() 主要的差别在於:

  _snprintf() (MSVC) snprintf()

  回传值当 len <= size 时,会回传 len

  当 len > size 时,会回传负值(-1)

  正常状况会回传 len。

  如果有错误,回传负值(-1)

  字串内容当 len < size 时,str 会包含结尾的 '\0'

  当 len >= size 时,str 不会有结尾的 '\0'

  str 会包含结尾的 '\0'

  len:要输出的字串应有的长度,不包含结尾的 '\0'。

  size:snprintf / _snprintf 的第二个参数,写到 str 的最大资料量。

  所以如果要跨平台,大致上应该可以:

  如果是使用 MSVC 的话,自行定义 snprintf,让它变成 _snprintf

  #ifdef _MSC_VER

  #define snprintf _snprintf

  #endif

  实际使用,则就可以直接用 snprintf

  int tmp = 10000;

  char cstr[20];

  int size = sizeof( cstr );

  int c = snprintf( cstr, size, "%d * %d = %d", tmp, tmp, tmp*tmp );

  if( c > size || c < 0 )

  cstr[ size 1 ] = '\0';

  这样应该就可以在 g++ 和 MSVC 的环境里,都可以避免 buffer overflow 和字串结尾没有 '\0' 的问题了~

  但是这样的做法,实际上是产生一个最大长度为 20 的字串,如果超过的话,虽然不会有 buffer overflow 的问题,但是过长的部分还是要切掉。而如果希望可以针对需要,产生一个够长的字串的话,其实还可以使用 asprintf() 这个函式。他的用法很简单,基本上和 sprintf() 很像,只是将第一个参数改成一个 char** 而已;下方就是简单的范例:

  char* cstr;

  int c = asprintf( &cstr, "%d * %d = %d", tmp, tmp, tmp*tmp );

  如此一来,他就会自动替 cstr 产生一块够大的记忆体空间,来存放字串了~

  不过 asprintf() 这个函式应该不在 C 语言的标准内,而是 GNU 的 extension(可能要加上「#define _GNU_SOURCE」才能使用),所以在 MSVC 里并没有提供 asprintf() 可以使用。不过虽然没有现成的可以用,但是还是可以透过执行两次 snprintf() 来做到同样的功能~实作的方法,大致上就是:

  char* cstr;

  int c = snprintf( NULL, 0, "%d * %d = %d", tmp, tmp, tmp*tmp );

  cstr = new char[ c + 1 ];

  snprintf( cstr, c + 1, "%d * %d = %d", tmp, tmp, tmp*tmp );

  做法的主要概念,就是第一次的 _snprintf() 实际上并不真正的将字串写到某个空间,而是单纯用来取得字串所需要的长度,然后再根据需要的长度来产生字元阵列,并将资料写入。
分享到:
评论

相关推荐

    qt实现的16进制显示界面

    qt实现的16进制显示控件,可以用来显示串口原始数据,同时支持字符串显示。资源为一个调用demo。用作参考。

    c-utilities:一些使 C 编程更容易的工具

    我用来使编写程序更好的各种 C 实用程序。...xmalloc :对象检查 malloc、calloc、realloc、strdup、asprintf。 如果函数未能分配所需的内存,它将退出程序。 progressmeter : 一个很好的文件操作进度信息

    需要系数法负荷计算软件.zip

    需要系数法负荷计算软件

    kettle插件-MongoDB Delete2.0

    kettle 用于(按条件)删除MongoDB集合数据的插件。 只需要放入kettle 客户端安装目录的 plugins目录下,然后重启kettle客户端即可。

    建筑电气负荷计算小软件.zip

    建筑电气负荷计算小软件

    电线选型、线管选型小型计算软件.zip

    电线选型、线管选型小型计算软件

    有限网卡驱动包,直接上传下载就行

    啦啦啦啦

    Theano-0.8.0.zip

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    临床信息.csv

    临床信息.csv

    Windows 命令行五子棋程序,用于向 STM32 移植Gobang.zip

    五子棋游戏想必大家都非常熟悉,游戏规则十分简单。游戏开始后,玩家在游戏设置中选择人机对战,则系统执黑棋,玩家自己执白棋。双方轮流下一棋,先将横、竖或斜线的5个或5个以上同色棋子连成不间断的一排者为胜。 【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、python、web、C#、EDA、proteus、RTOS等项目的源码。 【技术】 Java、Python、Node.js、Spring Boot、Django、Express、MySQL、PostgreSQL、MongoDB、React、Angular、Vue、Bootstrap、Material-UI、Redis、Docker、Kubernetes

    现金收支月报表Excel图表.xlsx

    现金收支月报表Excel图表.xlsx

    接地电阻计算软件.zip

    接地电阻计算软件

    多人联机五子棋小游戏muti-Gomoku-master.zip

    五子棋游戏想必大家都非常熟悉,游戏规则十分简单。游戏开始后,玩家在游戏设置中选择人机对战,则系统执黑棋,玩家自己执白棋。双方轮流下一棋,先将横、竖或斜线的5个或5个以上同色棋子连成不间断的一排者为胜。 【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、python、web、C#、EDA、proteus、RTOS等项目的源码。 【技术】 Java、Python、Node.js、Spring Boot、Django、Express、MySQL、PostgreSQL、MongoDB、React、Angular、Vue、Bootstrap、Material-UI、Redis、Docker、Kubernetes

    spring aop实现接口参数变更前后对比和日志记录

    spring aop实现接口参数变更前后对比和日志记录完整代码,拿到项目代码,只需要做数据库连接的修改即可运行起来使用,代码案例详细,真是可靠,代码原文地址:https://blog.csdn.net/zhangcongyi420/article/details/138748857?spm=1001.2014.3001.5501

    setuptools-58.5.1.tar.gz

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    控制台界面字符版五子棋,有AI,可人机对战,在dev-c++下编写Renju-AI.zip

    五子棋游戏想必大家都非常熟悉,游戏规则十分简单。游戏开始后,玩家在游戏设置中选择人机对战,则系统执黑棋,玩家自己执白棋。双方轮流下一棋,先将横、竖或斜线的5个或5个以上同色棋子连成不间断的一排者为胜。 【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、python、web、C#、EDA、proteus、RTOS等项目的源码。 【技术】 Java、Python、Node.js、Spring Boot、Django、Express、MySQL、PostgreSQL、MongoDB、React、Angular、Vue、Bootstrap、Material-UI、Redis、Docker、Kubernetes

    母亲节祝福html源码.zip

    母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福html源码母亲节祝福

    二叉树遍历算法的应用hahhhahaha

    二叉树遍历算法的应用hahhhahaha

    变压器DGA溶解气体数据(357组)

    包含六种故障类型: 中低温过热 高温过热 低能放电 高能放电 局部放电 正常 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111需要直接下载就可

    桌面滚动字幕软件(2.0)一款可以实现无限循环自定义循环内容的电脑屏幕桌面走字的软件.rar

    桌面滚动字幕软件(2.0)是一款功能强大的电脑屏幕桌面走字工具。它能够实现无限循环自定义循环内容,让用户可以将想要展示的文字内容在电脑屏幕上滚动显示。无论是在办公、学习、展示、宣传等场景,都能发挥重要作用。 这款软件具有以下特点和优势: 1. 自定义内容:用户可以自由编辑、添加、删除和修改滚动字幕的内容,满足个性化需求。 2. 无限循环:字幕内容可以无限循环播放,确保重要信息持续传达。 3. 多种字体、颜色和大小:支持多种字体、颜色和大小的选择,让滚动字幕更具吸引力。 4. 灵活的滚动速度:用户可以根据需求调整滚动速度,实现流畅的滚动效果。 5. 定时功能:可设置滚动字幕的自动隐藏和显示时间,提高屏幕的使用效率。 6. 简洁易用:界面简单直观,操作方便,无需专业知识即可快速上手。 7. 兼容性强:适用于各种Windows操作系统,如Windows 7、Windows 8、Windows 10等。 8. 占用资源低:软件运行过程中,占用极低的系统资源,不影响电脑的正常使用。

Global site tag (gtag.js) - Google Analytics