小明思考

高性能服务器端计算
posts - 64, comments - 325, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

谈谈snprintf

Posted on 2006-09-29 10:27 小明 阅读(5751) 评论(4)  编辑 收藏 引用 所属分类: C/C++
众所周知,sprintf不能检查目标字符串的长度,可能造成众多安全问题,所以都会推荐使用snprintf.

snprintf(_snprintf)的声明是这样的

int _snprintf(
   char *buffer,
   size_t count,
   const char *format [,
      argument] ...
);

If len < count, then len characters are stored in buffer, a null-terminator is appended, and len is returned.

If len = count, then len characters are stored in buffer, no null-terminator is appended, and len is returned.

If len > count, then count characters are stored in buffer, no null-terminator is appended, and a negative value is returned.


最常见的错误用法有:
1.
char sa[256]={0};
_snprintf(sa,sizeof(sa),"%s",sb);
//错误原因:当sb的长度>=256的时候,sa将没有'\0'结尾

2.
char sa[256];
_snprintf(sa,sizeof(sa)-1,"%s",sb);
//错误原因:当sb的长度>=255的时候,sa将没有'\0'结尾,忘记给sa初始化

3.
char sa[256];
_snprintf(sa,sizeof(sa)-1,"%s",sb);
sa[sizeof(sa)]=0;
//错误原因:最后一行数组越界

正确的用法
1. //推荐用法
char sa[256];
sa[sizeof(sa)-1]=0;
_snprintf(sa,sizeof(sa),"%s",sb);
if(sa[sizeof(sa)-1]!=0)
{
   printf("warning:string will be truncated");
   sa[sizeof(sa)-1]=0;
}

2.
char sa[256]={0};
int result = _snprintf(sa,sizeof(sa),"%s",sb);
if(result==sizeof(sa) || result<0)
{
    printf("warning:sting will be truncated");
   sa[sizeof(sa)-1]=0;
}

Feedback

# re: 谈谈snprintf  回复  更多评论   

2006-09-30 16:48 by 阿福
朋友,我觉得我的方法更简单,更好:
char sa[256];
_snprintf(sa, sizeof(sa), "%s\0", sb);
//在格式化的时候要求在最后加一个0就行了嘛!

# re: 谈谈snprintf  回复  更多评论   

2006-09-30 18:15 by 小明
TO 阿福:
你这样是不行的。简化一下说明一下
char sa[2];
char sb[3]="aa";
_snprintf(sa, sizeof(sa), "%s\0", sb);

==> sa="aa",但是没有'\0'结束

# re: 谈谈snprintf  回复  更多评论   

2006-10-18 17:36 by Sim
TO 小明

你们用的都是什么系统啊
在linux下从来都是
char sa[2];
char sb[3]="aa";
snprintf(sa, sizeof(sa), "%s", sb);
这样用的, 而且sa=>"a", 系统会自动阶段

# re: 谈谈snprintf  回复  更多评论   

2007-06-03 01:19 by yecheng_110
linux和windows下是不同的
linux下的snprintf没有这个问题
而windows下的_snprintf才有这个问题

标题  
姓名  
主页
验证码 *
内容(提交失败后,可以通过“恢复上次提交”恢复刚刚提交的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
[使用Ctrl+Enter键可以直接提交]
相关链接:
网站导航: