[C语言笔记]undefined behavior: sprintf/snprintf
测 试 四月 28th, 2009
对下面这样的写法,大家可能不陌生:
使用这个语句的最初目的,是用来实现格式化字符处理版本的’strcat’。
但是这么写是有问题的,看下面这个例子:
2 #include
3
4 int main(void)
5 {
6 char buf[20];
7
8 memset(buf, ‘\0′, sizeof(buf));
9 strcpy(buf, “FOO”);
10 snprintf(buf, sizeof(buf), “%s%s”, buf, “BAR”);
11 printf(”%s\n”, buf);
12
13 memset(buf, ‘\0′, sizeof(buf));
14 strcpy(buf, “BAR”);
15 snprintf(buf, sizeof(buf), “%s%s”, “FOO”, buf);
16 printf(”%s\n”, buf);
17 }
大家可能期望其输出是:
FOOBAR
但是,实际输出是:
FOOFOO
C标准draft文档n1362.pdf有这么一段(P308):
7.19.6.6 The sprintf function
Synopsis
1 #include
int sprintf(char * restrict s,
const char * restrict format, …);
Description
2 The sprintf function is equivalent to fprintf, except that the output is written into
an array (specified by the argument s) rather than to a stream. A null character is written
at the end of the characters written; it is not counted as part of the returned value. If
copying takes place between objects that overlap, the behavior is undefined.
Returns
3 The sprintf function returns the number of characters written in the array, not
counting the terminating null character, or a neg ative value if an encoding error occurred
即按照标准,sprintf的形参(parameter)是带restrict关键字的,即认为这些参数指向的东西不会在sprintf() 调用时同时被访问到,“sprintf(buf, “%s foo %d %d”, buf, var1, var2);”这样写法,实参(argument)buf在两处同时被访问到了,这样就造成 undefined behavior。
C库没有义务保证这样的代码的有效性。
避免办法:
1、使用strcat
2、增加一个变量
参考链接:
最近评论