snprintf

sprintf和snprintf的正确使用

假如想象 提交于 2020-04-15 17:01:21
【推荐阅读】微服务还能火多久?>>> 关于sprintf和snprintf的正确使用 考虑以下有缺陷的例子: void f(const char *p) { char buf[11]={0}; sprintf(buf,"%10s",p); // very dangerous printf("%sn",buf); } 不要让格式标记“%10s”误导你。如果p的长度大于10个字符,那么sprintf() 的写操作就会越过buf的边界,从而产生一个缓冲区溢出。 检测这类缺陷并不容易,因为它们只在 p 的长度大于10个字符的时候才会发生。黑客通常利用这类脆弱的代码来入侵看上去安全的系统。 要修正这一缺陷,可以使用函数snprintf()代替函数sprintf()。 函数原型:int snprintf(char *dest, size_t n, const char *fmt, ...); 函数说明: 最多从源串中拷贝n-1个字符到目标串中,然后再在后面加一个0。所以如果目标串的大小为n的话,将不会溢出。 函数返回值: 若成功则返回存入数组的字符数,若编码出错则返回负值。 推荐的用法: void f(const char *p) { char buf[11]={0}; snprintf(buf, sizeof(buf), "%10s", p); // 注意:这里第2个参数应当用sizeof

snprintf和sprintf区别分析

﹥>﹥吖頭↗ 提交于 2020-04-15 16:44:14
【推荐阅读】微服务还能火多久?>>> 今天在项目中使用snprintf时遇到一个比较迷惑的问题,追根溯源了一下,在此对sprintf和snprintf进行一下对比分析。 因为sprintf可能导致缓冲区溢出问题而不被推荐使用,所以在项目中我一直优先选择使用snprintf函数,虽然会稍微麻烦那么一点点。这里就是sprintf和snprintf最主要的区别:snprintf通过提供缓冲区的可用大小传入参数来保证缓冲区的不溢出,如果超出缓冲区大小则进行截断。但是对于snprintf函数,还有一些细微的差别需要注意。 snprintf函数的返回值 sprintf函数返回的是 实际输出 到字符串缓冲中的字符个数,包括null结束符。而snprintf函数返回的是 应该输出 到字符串缓冲的字符个数,所以snprintf的返回值可能大于给定的可用缓冲大小以及最终得到的字符串长度。看代码最清楚不过了: char tlist_3[10] = {0}; int len_3 = 0; len_3 = snprintf(tlist_3,10,"this is a overflow test!\n"); printf("len_3 = %d,tlist_3 = %s\n",len_3,tlist_3); 上述代码段的输出结果如下: len_3 = 25,tlist_3 = this is a