由sprintf引发的思考
最近在做一个项目中,之前编码阶段为了图省事,使用了sprintf来把整形转换字符串类型。并且在我的一个vector数据中使用到这个sprintf转换的字符串数据,问题就接踵而来...
先看个列子:
1 #include <stdio.h> 2 #include <string.h> 3 char ctemp[] = {'\0', '\0'}; 4 int main() 5 { 6 int result = 100; 7 sprintf(ctemp, "%d", result); 8 printf("result is: %s\n", ctemp); 9 return 0; 10 }
在VC7.0上,这段代码欲行并没有什么问题,也能正常输出结果:
result is: 100 Press any key to continue
接下来我们改动一下代码,改成下面这个样子:
1 #include <stdio.h> 2 #include <string.h> 3 4 int main() 5 { 6 int result = 100; 7 char ctemp[] = {'\0', '\0'}; 8 sprintf(ctemp, "%d", result); 9 printf("result is: %s\n", ctemp); 10 return 0; 11 }
然后再次在VC7.0上编译运行,会弹出栈溢出的错误提示:
Run-Time Check Failure #2 - Stack around the variable 'ctemp' was corrupted.
后来经一位高人指点,说最好还是不要使用sprintf,可以使用snprintf代替,下面是在不同平台上snprintf伪码的实现原理。
1 vc2003 2 len = _snprintf (buf, n, srcbuf); 3 strlen(srcbuf) >= n 4 len = -1 5 buf <- srcbuf[0,n] 6 64 7 %i64d 8 9 10 vc2005 2008 2010 11 snprintf 12 13 gcc 14 len = snprintf (buf, n, srcbuf); 15 strlen(srcbuf) >= n 16 len = strlen(srcbuf) < n 时长度 17 buf <- srcbuf[0,n-1] \0 18 19 64 20 %lld