sprintf (buffer, "and %d minus %d is %d", 6, 3, 6-3);
重写buffer
而不是连接。先前的原始结果sprintf()
丢失。
strcat(c, buffer);
附加buffer
到自身。由于重叠,它是未定义的行为(UB)。不要那样做。
而是使用sprintf()
(打印的字符数)的返回值来确定胶印。
int offset = sprintf (buffer, "%d plus %d is %d", 5, 3, 5+3);
offset += sprintf (buffer + offset, " and %d minus %d is %d", 6, 3, 6-3);
offset += sprintf (buffer + offset, " even more");
printf ("[%s]",buffer);
避免strcat()
,因为这需要代码迭代先前的字符串,从而导致Schlemiel the Painter's Algorithm。最好跟踪字符串长度并将其用于下一个sprintf()
.
可以使用更好的代码snprintf()
来防止缓冲区溢出。
// Pedantic example
char buffer [100];
size_t offset = 0;
size_t available = sizeof buffer;
int retval = snprintf (buffer, available, "%d plus %d is %d", 5, 3, 5+3);
if (retval < 0 || (unsigned) retval >= available) Handle_Overflow();
offset += retval;
available -= retval;
retval = snprintf (buffer + offset, available, " and %d minus %d is %d", 6, 3, 6-3);
if (retval < 0 || (unsigned) retval >= available) Handle_Overflow();
offset += retval;
available -= retval;
retval = snprintf (buffer + offset, available, " even more");
if (retval < 0 || (unsigned) retval >= available) Handle_Overflow();
offset += retval;
available -= retval;
printf ("[%s]",buffer);
句子的长度和数量是无限的。
通常一个大的缓冲区就足够了,因为无限制并不是真正的无限制,只是可能很大。C字符串仅限于SIZE_MAX
.
替代方案:研究非 C 标准asprintf()
。