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
情况如下:
我们从使用 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