范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

C函数snprintf的用法和避免踩坑

  snprintf 函数是C语言中非常常用的一个函数,它的作用是格式化一段文本放到指定的缓存中。和它类似的还有sprintf, vsnprintf等。它们都完成类似的功能,但又有些区别,如sprintf 是不会检查输出缓存的长度的,需要调用者确保长度是足够的。vsnprintf 函数和snprintf 很像,但它是通过 va_list 来传入格式化参数,所以一般用于传入了可变的需要格式化字符串的函数内。而我们最常用的就是snprintf 了,因为它具有缓冲区的溢出保护。
  snprintf函数的原型如下: int snprintf(char *str, size_t size, const char *format, ...);
  其中: str 传入输出缓冲区的地址;size指出输出缓冲区的大小;format 为传入的格式化字符串;其后的参数就是格式化的参数了。
  该函数返回一个整数,表示格式化后的文本大小。通过这个返回值,我们可以做很多事情。也正是对这个返回值的理解不够或者使用错误,我们往往会踩一些坑。
  最普通的用法是使用该函数来格式化一段文本,如: char   szText[1024]; int    a=10, b=20; snprintf(szText, sizeof(szText), "%d + %d = %d", a, b, a+b);
  该函数具有缓冲区保护的功能,如果格式化输出内容超过了缓冲区的最大长度,那么输出字符串会被截断到缓冲区的最大长度。同时无论如何,字符串最后的结尾 ‘’ 是一定会有的,保证了输出的字符串不会溢出。所以这也是广大程序员喜欢使用这个函数的原因。
  如果我们需要格式化一个具有多个元素的数组,那么这个时候就可以充分利用snprintf的返回值了。我们只需要反复调用snprintf 并移动缓冲区的起始位置就能实现。代码如下: char   szText[1024];     // 输出的缓冲区 int   a[100] = {...};    // 假设会有代码逻辑填充这个数组的内容 int   n;    // 循环数组的下标 int   len = snprintf(szText, sizeof(szText), "a= {");     // 保存输出字符串的长度 for  (n = 0; n < 100; n++) {     len += snprintf(szText + len, sizeof(szText)-len, "%d, ", a[n]); } len += snprintf(szText + len, sizeof(szText)-len, "}");
  这段代码看起来能正常工作,通常也确实可以正常工作,但是前提条件是 szText的缓冲区大小是足够大的。如果缓冲区的大小不够会发生什么情况?你不妨改小szText再试试。
  那么为什么会出现问题呢?首先我们要深入理解一下snprintf 返回值的含义。按前面所述,返回值表示格式化后文本的大小,注意不是返回输出缓冲内的字符串长度。什么意思呢,也就是说,如果输出的缓冲足够大,大到可以容纳所有的输出文本,那么这个返回的长度恰恰就是输出缓存中的字符串长度。如果输出缓冲不够大,或者根本就没有传入输出缓冲这个参数呢?返回值就和实际的输出文本长度不一样了。为什么是这样?其实这个函数本来也是可以用来计算格式化所需要的最小缓存大小,并根据返回值来实际分配输出缓冲的内存。如下代码所示的用法: int a = 10; int b = 20; char* pszOut = NULL;  // 输出缓存指针 int len; len = snprintf(NULL, 0, "%d + %d = %d", a, b, a+b);  // 计算需要的输出长度。 pszOut = (char*)alloca(len+1); // 需要考虑结尾的0 战用一个字符 snprintf(pszOut, len+1, "%d + %d = %d", a, b, a+b);
  有人会疑惑,为什么需要这样写?上面这个例子可能不明显。但是如果需要格式化的内容不固定,长度变化范围很大。那么就有可能不太好使用固定大小的缓冲。
  理解了这个返回值的含义和用法,再回到上面那个循环调用的例子。我们需要加上对长度的校验就没有问题了: char   szText[1024];     // 输出的缓冲区 int   a[100] = {...};    // 假设会有代码逻辑填充这个数组的内容 int   n;    // 循环数组的下标 int   len = snprintf(szText, sizeof(szText), "a= {");     // 保存输出字符串的长度 for  (n = 0; n < 100 && len < sizeof(szText); n++) {     len += snprintf(szText + len, sizeof(szText)-len, "%d, ", a[n]); } len += snprintf(szText + len, sizeof(szText)-len, "}");
  如果有什么疑问,欢迎一起讨论。

走在云网价值服务的路上盘点鹏博士太古云通2020年10月,鹏博士向全资子公司北京太古云通公司增资9000万2020年年报,鹏博士正式公告确立云网一体化战略2021年2月,以太古云通为主体,鹏博士与阿里云签署战略协议20211年来好丽友首次涨价!企业降本增效真的很难吗?据报道,9月1日起,好丽友旗下部分派类产品价格将上涨。这是过去11年来中国好丽友旗下产品首次涨价。在业内人士看来,近年来消费者健康意识不断提升,好丽友巧克力派等产品销量增长出现放缓企业云服务爆发在即,鹏博士新推数字合伙人疫情爆发后,远程办公在线教育远程医疗等需求猛增,政企数字化转型不断加速。国家新型基础设施建设的发展规划驱动下,云计算作为新基建的底座,为数字经济按下了快进键。我国企业云服务步入发展再添原谅色新机?红米Note8撞脸友商预警今日10点,红米官宣了打响下米家半年手机大战的首发选手RedmiNote8将于8月29日和大智慧的70英寸巨屏电视一起亮相。从官博发的图来看,此次主打的确实如之前猜测的那样,是三星LGD逆袭一局?抛弃京东方后,华为Mate30能反超iPhone11吗?据外媒昨日消息,华为Mate30系列的屏幕或将采用LGD家的柔性OLED面板,而放弃此前钟爱的京东方的屏幕。其实,今年早些时候,华为的P30系列都是采用的京东方家的柔性屏。虽然有被抓住iPhone11不放的余承东,和碰瓷荣耀的卢伟冰有什么不同?昨晚,众望所归的华为Mate30系列终于在德国正式亮相了。不知道是之前泄露的信息都差不多了,还是期望太高,昨晚的华为Mate30系列没有给人一种比较惊艳的感觉。屏幕外观设计上,要说小程序为什么目前取代不了App,本质差异在哪儿?虽然现在手机内存越做越大,但问问君身边的朋友都抱怨说内存不够,很多App都装不了。其实,问问君手机的内存也不大,但是基本上大家手机有的功能我也都有。这是为什么呢?主要在于问问君将一哈弗神兽除了哈弗H6,哈弗品牌终究还需要一个牌面文二哥头赶在10月最后一天,哈弗品牌的最新旗舰车型哈弗神兽开启了预售,价格区间在13。2万元16。9万元,提供1。5T和2。0T两个动力版本,一共6款车型。当然,预售大礼包也没有缺井喷期到了,如何成为信创云计算专家?导读未来的发展,加快政企数字化,建设数字中国,将会无产业不信创,无行业不信创。信创已经成为了百行百业的发展常态,特别是信创云计算,也已成为了2021年数字新基建发展的焦点之一。信创长城首个高端轿车品牌诞生!长城如何把哈弗的神话延续到轿车?文Lei抛开那些商业因素不谈,作为一个小小的汽车撰稿人,在我不短不长接触汽车行业的这些日子里,大方承认我确实欣赏长城这个品牌欣赏它的风格欣赏它的企业文化,我并不觉得是一件不好意思的哈弗H6S正式上市!售价13。89万起,点燃运动灵魂开启年轻新潮流文岸青哈弗品牌作为SUV的销量领跑者,近几年来,一直有着不错的好评口碑,为了献礼哈弗H6十周年,哈弗再创新成员,新世代潮跑利器哈弗H6S于10月30日正式上市。新车定位轿跑SUV,
券商回应APP违法违规被通报检测提取的APP版本非官方正式发布南方财经4月25日电,国家计算机病毒应急处理中心近期通过互联网监测发现17款移动App存在隐私不合规行为,涉及13家券商APP和4家第三方炒股软件,违反网络安全法个人信息保护法等相快手616购物节招商启动全程30天所有商家均可参与亿邦原创日前,快手电商召开了2022年616实在购物节招商启动会。本次616实在购物节以实在人,实在货,实在价为主题,整个活动划分为备战期(4月28日5月19日)和活动期(5月20终于懂什么是分布式锁为什么要有分布式锁?模拟一个秒杀接口商品表单机情况下,用Jmeter发送1000个请求过来由于加了sychronized进行方法同步,结果正常。现在模拟集群环境,还是用上面的接口,长视频困在会员系统里编辑导语会员系统自问世到现在已然被用户接受,长视频平台的会员费一直以来是其盈利的大头。而会员系统并没有那么完美,长视频被困在会员系统中,饱受争议,一起跟着作者探究一下吧!视频网站又618电商平台iPhone手机价格随着电商平台大促日常化,前些年隔三差五的促销已经让消费者麻木,全年下来真正有影响力的两个促销节点,就剩618跟双11了。这两个节点更是消费者剁手之路上越不过去的坎。而智能手机的消费有哪些去视频黑边的免费app?感谢邀请回答!1去除视频黑边的软件,推荐MP4RM转换专家软件可以将视频中的黑边去除掉,处理速度是较快的,导入rmvb视频,选择导出avi格式,在人性化影片画面裁剪功能,对视频黑边三部门目标到2022年末,IPv6活跃用户数达到7亿网信办4月25日消息,日前,中央网信办国家发展改革委工业和信息化部联合印发深入推进IPv6规模部署和应用2022年工作安排,明确了2022年工作目标到2022年末,IPv6活跃用户不敢与三星,苹果竞争,国产手机是软蛋?前两天聊国产手机集中冲高端,导致了不少品牌上的问题,有很多人都表示中国手机就是怂炮,只会窝里斗,为什么不一致对外?这个所谓的一致对外就是很扯的东西,首先现在手机竞争并没有涉及到国家究竟什么是AppleID?什么是appleID?appleID是你在整个apple生态系统中的个人账户只需一个账户你就能访问所有apple产品和服务例如icloudappstore等等这意味着,如果你只用自手机用久了,电池不耐用了怎么办?涨知识了冷知识手机用久了,电池越来越不耐用。一是由于电池损耗,寿命减少。二是由于产生虚电,从而导致手机电池不耐用。这时,先别急着去更换手机电池,可以试试手机上的补电功能,也许能够解决电池不耐用的再次确定!vivoS15Pro下个月发布,4大升级让人心动4月25日消息,知名数码博主站哥曝光了vivoS15Pro的更多细节,再次提高了网友们对这款自拍旗舰的期待。结合此前的爆料和入网信息可知,vivoS15Pro将于5月份发布,在硬件