安庆大理运城常德铜陵江西
投稿投诉
江西南阳
嘉兴昆明
铜陵滨州
广东西昌
常德梅州
兰州阳江
运城金华
广西萍乡
大理重庆
诸暨泉州
安庆南充
武汉辽宁

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

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

一辈子都不换电话号码的是什么人?这种好多年不换电话号码的人有个有很多吧!我就是其中一个,我的号码是2010年来温州的时候买的,快十年了,对于一辈子不换号码的有一下几点:一是这个号码用的久了绑定了支付宝,……如果用一句话来说说你来到头条的最大收获,你会怎么说?渤谢邀请:我会这么说:收获满满。来到今日头条,我从一个无知到学会玩一些智能手机功能,总的收获有如下产品:一是认识了不同界面的人。如军事专家,军事学者,资深学者,教授……中科营商大数据科技(北京)有限公司诚聘英才【招聘高级研究员2名】中科营商大数据(北京)科技有限公司,中科营商环境大数据研究院公司的爱国主义核心价值观:做正能量的事,赚正当的干干净净的钱,把企业事业与国……售价9999元起!华为荣耀也出折叠手机了,发布会PPT秒杀小去年年底,不少手机大牌发布会就没有断过,其中三星、华为、小米都发布了折叠手机!昨天荣耀的发布会上,荣耀CEO赵明正式发布了荣耀首款折叠屏手机MagicV,搭载全新一代骁龙……时隔多年,IDG资本再出手投资农业公司记者李馨婷管丢丢农业投资周期长、回报慢,一直以来很难受到资本青睐。2012年,IDG资本董事长熊晓鸽在接受采访时表示,做农业比较难,因为涉及食品安全问题,因此对投资……初中毕业被清华破格录用!他每篇论文都有资格获得博士学位,但一来源:微信公众号共青团中央(ID:gqtzy2014)综合整理自微信公众号CCTV国家记忆(ID:cctvguojiajiyi)、科学大院(ID:kexuedayuan)、联合……推荐4款顶尖黑科技app,每款都精心挑选推荐4款顶尖黑科技app,每款都精心挑选手机上很多好用的app,这里就来推荐4款顶尖的黑科技app,每款都精心挑选,请你低调使用。1、实用工具箱适用:安卓、i……从莆田事件开始,有没有发现最近刑事案件频频出现?我认为,其实不是刑事案件频频出现。1、随着社会的发展,很多城市都开展建设了诸如平安工程、雪亮工程等项目,在全国范围内建设密布着高清探头,犯罪率相比之前已经大大降低了。再加……1月26号股市企稳,新能源医疗一触即发,马上进入小牛是第一天新能源医疗跌无可跌,从明天开始,要好好爱护自己的眼睛,一样爱护自己的股票。三天小牛市已经来临了,大涨一触即发。明天中国最大最大主力进入股市,我们广大股友再也不用害怕啦。大……对话李泽湘孵化大疆云鲸后,怎么培养更多科技创始人中国越来越意识到那些短平快的、拿来主义的东西已经走到头了,而这是最好的时机。文程曼祺编辑宋玮李泽湘喜欢爬山徒步,最极致的一次是53岁时,他在38小时里走完了1……C函数snprintf的用法和避免踩坑snprintf函数是C语言中非常常用的一个函数,它的作用是格式化一段文本放到指定的缓存中。和它类似的还有sprintf,vsnprintf等。它们都完成类似的功能,但又有些区……这4件家电没必要买太贵的,能满足基本功能,普通款就足够了家用电器已经成为每个家庭生活的必需品,大家在选购时更愿意相信产品是一分钱一分货,会盲目地认为贵有贵的道理,根本不考虑自己的实际需要,一味的去追求品牌的高端款。但其实家电行……
外媒拜登亚洲行将聚焦对华竞争天文学家发现一颗现实中的行星有两个太阳就像星球大战中的amp支付宝集五福的活动又来了刘昊然工作室报警!AI换脸源自黑科技DeepFake,究竟有小米新系统曝光,CPU时间减少22,首发机型确认令库克都感到有威胁的三款国产旗舰,看看有你正在用的吗?Filecoin和Arweave的区别在哪里?谁更有前途?10公里超大覆盖语音对讲!极蜂超薄对讲机A306让多人沟通更售价500元以下这款打印机真心适合家用特斯拉在欧洲首座超级工厂开工并交付新车二千左右能买到什么样的二手手机?理论智库丨如何全面提升湖南科技创新的核心竞争力实现高水平科技

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找七猫云易事利