sprintf( )函数主要用来将格式化参数写入字符串中,函数包含与头文件中,函数执行成功,其返回值为字符串的长度,执行失败返回-1.

01  用法解析

f8e29d6e2088329cecd206e9781bdabc.png

头文件:#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 使用弊端

71d711e35fbe1b613ee586f9a7f54339.gif

sprintf( )函数虽然好用,但是不够安全,容易出现翻车现象。

例如:将例子中的 time[30]改为time[10],写入的字符串的长度超过了字符串数组time的长度,造成缓冲区溢出。字符数组空间预估的小了,而sprintf在执行时不会考虑前面的字符串数组空间是否足够,它会自动地占用后续空间,这样就会影响后面的数据。

03 解决方案

bbb1bf41f91f1db9f015ccd5f654c0bb.gif

使用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 总结

58a94b0507cf4e5b3b1f97d73f8ce20f.png

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

想看更多内容请关注我们吧!

54c56b4d59347f87ce2f19300ad3d0af.png

Logo

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

更多推荐