sprintf 的最佳实践?

Best practice with sprintf?

情况如下:

我们从使用 strcat 等 sprintf 的外部来源收到代码。像这样:

char buffer[1024];
sprintf(buffer, "Some text.");
sprintf(buffer, "%s%s", buffer, "Some more text");
sprintf(buffer, "%s%s", buffer, "again more text");

现在,这看起来很奇怪。我们都同意这看起来很奇怪。那不是我要问的。我们都知道应该用strcat,而且更直接。我问的是这可能导致的潜在问题,除了看起来很奇怪。我们 运行 在 RHEL6 上,使用 gcc 4.9.3。

感谢您的帮助。

函数声明为

int sprintf(char * restrict s, const char * restrict format, ...);

注意类型限定符restrict

根据C标准(7.21.6.6的sprintf函数)

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.

所以这些电话

sprintf(buffer, "%s%s", buffer, "Some more text");
sprintf(buffer, "%s%s", buffer, "again more text");

调用未定义的行为。

相反,调用可以这样写

char buffer[1024];
int offset = 0;

offset = sprintf( buffer + offset, "Some text.");
offset += sprintf( buffer + offset, "%s",  "Some more text");
sprintf( buffer + offset, "%s",  "again more text");

char buffer[1024];
char *p = buffer;

p += sprintf( p, "Some text.");
p += sprintf( p, "%s",  "Some more text");
sprintf( p, "%s",  "again more text");

至于限定词restrict那么一般来说就是指(6.7.3类型限定词)

8 An object that is accessed through a restrict-qualified pointer has a special association with that pointer. This association, defined in 6.7.3.1 below, requires that all accesses to that object use, directly or indirectly, the value of that particular pointer