小明思考

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

谈谈snprintf

Posted on 2006-09-29 10:27 小明 阅读(34445) 评论(8)  编辑 收藏 引用 所属分类: 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才有这个问题

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

2009-05-03 12:33 by 创意产品
学习了,谢谢

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

2010-01-05 09:57 by axwinter
xiexie!!!!!!!!

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

2012-05-10 13:05 by wenson
阿福:"%s\0"这个常量尽管占用4个char位置,后两个都是0,但是对snprintf含糊来说,遇到第一个结束符就认为结束了。等价于"%s".

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

2015-03-16 10:17 by 许余胜
windows下:
char sa[256]={0};
_snprintf(sa,sizeof(sa) - 1,"%s",sb);
或者
char sa[256]={0};
_snprintf(sa,sizeof(sa) -1 ,sb);
Linux下:
char sa[256]={0};
snprintf(sa,sizeof(sa),"%s",sb);
或者
char sa[256]={0};
snprintf(sa,sizeof(sa),sb);



只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理