sprintf 头文件_嵌入式编程:谈sprintf( )函数
01 用法解析

头文件:#include
sprintf()函数用于将格式化的数据写入字符串,原型为:
int sprintf(char *str, char * format [, argument, ...]);
【参数】str为要写入的字符串;format为格式化字符串,与printf()函数相同;argument为变量。
除了前两个参数类型固定外,后面可以接任意多个参数。
printf()和sprintf()都使用格式化字符串来指定串的格式,在格式串内部使用一些以“%”开头的格式说明符(format specifications)来占据一个位置,在后边的变参列表中提供相应的变量,最终函数就会用相应位置的变量来替代那个说明符,产生一个调用者想要的字符串。
例:
u8 time[30];
sprintf((char*)time,"%d/%d/%d%d:%d:%d",calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);
02 使用弊端

sprintf( )函数虽然好用,但是不够安全,容易出现翻车现象。
例如:将例子中的 time[30]改为time[10],写入的字符串的长度超过了字符串数组time的长度,造成缓冲区溢出。字符数组空间预估的小了,而sprintf在执行时不会考虑前面的字符串数组空间是否足够,它会自动地占用后续空间,这样就会影响后面的数据。
03 解决方案

使用snprintf()函数。snprintf是sprintf的安全版本,其函数原型为:
int _snprintf(char *str, size_t size, const char *format, ...);
用途:
将可变参数(...)按照format格式化成字符串,然后将其复制到str中
(1) 如果格式化后的字符串长度 < size,则将此字符串全部复制到str中,并给其后添加一个字符串结束符('\0');
(2) 如果格式化后的字符串长度 >= size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符('\0'),返回值为欲写入的字符串长度。
使用例子:
u8 time[30];
_snprintf((char*)time,sizeof(time),"%d/%d/%d%d:%d:%d",calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);
04 总结

sprintf( )函数虽然好用,但是缓冲区大小预估不对,容易造成溢出,造成数据改写。推荐使用_snprintf(),指定缓冲区大小,保障程序更加安全可靠不跑飞。
想看更多内容请关注我们吧!

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)