本文主要是介绍vsprintf缓冲区溢出问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目标:为string对象提供一个printf形式的格式化函数
方法:vsprintf先输出到一个char[],再拷贝到string变量中
问题:vsprintf输出的char[]缓冲区该开多大?
开小了可能不够,开大了浪费空间,多大是够大?
有没有函数能预先计算出目标串的长度?
有没有其他思路解决这个问题?
char fmt_buf[4096];
int stringprintf( string& str, char* fmt, ... )
{
va_list args;
va_start(args, fmt);
if ( vsnprintf ( fmt_buf, sizeof(fmt_buf)-1, fmt, args ) < 0 ) return -1;
str = fmt_buf;
va_end(args);
return ( str.size() );
}
想到个复杂的办法
虽然不能预先知道多大,但缓冲区不够大时是可以发现的,发现不够大时malloc扩大一倍缓冲区,一直到够大为止
len=1024; //初始缓冲区1024
buf=malloc(len);
while ( vnsprintf(buf,...) == -1 && len <1M ) { // 缓冲区不够大
len *= 2; // 缓冲区扩大一倍
buf=realloc(len);
}
好象有点疯狂
代码说话,这是从我工程里摘取的: C/C++ code ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | shared_ptr<string> format( const char * fmt, ...) { va_list ap; va_start (ap, fmt); vector< char > buf(1024); int ret; while ((ret = vsnprintf_s(&buf[0], buf.size(), buf.size(), fmt, ap)) == -1) { buf.resize(buf.size() * 2); } va_end (ap); if (ret == static_cast < int >(buf.size())) { buf[buf.size() - 1] = '\0' ; } return shared_ptr<string>( new string(&buf[0])); } | |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 | TOP |
- hairetz
- 心欲小而智欲大
- 等级:
更多勋章 |
#14 得分:0回复于: 2009-04-11 11:17:51 |
C/C++ code ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | int stringprintf( string& str, int num, int max, char * fmt, ... ) ; int main( int argc, char *argv[]) { int n; string str; n=stringprintf(str,2,20, "%d %s" , 123, "abcde" ); cout<<str<<endl; return 0; } int stringprintf( string& str, int num, int max, char * fmt, ... ) { va_list args; va_start (args, fmt); char *fmt_buf= new char [num*max]; if ( _vsnprintf ( fmt_buf, num*50, fmt, args ) < 0 ) return -1; str = fmt_buf; delete []fmt_buf; va_end (args); return ( str.size() ); } | 只能这样了。 |
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 | TOP |
- nde123456
- 该用户很懒,没设置昵称
- 等级:
|
#15 得分:0回复于: 2009-04-11 11:19:08 |
13楼的老兄:还真有人这么干啊,看来不是我一个人在钻牛角尖 声明一下,我12楼的内容不是抄你的哦,纯属巧合,看看发表时间和楼层号就知道,呵呵 |
这篇关于vsprintf缓冲区溢出问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!