您可以使用snprintf 函数,第一个参数为NULL,第二个参数为0,获取格式化字符串的大小。然后您可以动态分配空间并再次调用snprintf 来实际构建字符串。
char *buffer = NULL;
int len, offset = 0;
len = snprintf (NULL, 0, "%d plus %d is %d", 5, 3, 5+3);
buffer = realloc(buffer, offset + len + 1);
offset = sprintf (buffer + offset, "%d plus %d is %d", 5, 3, 5+3);
len = snprintf (NULL, 0, " and %d minus %d is %d", 6, 3, 6-3);
buffer = realloc(buffer, offset + len + 1);
offset += sprintf (buffer + offset, " and %d minus %d is %d", 6, 3, 6-3);
len = snprintf (NULL, 0, " even more");
buffer = realloc(buffer, offset + len + 1);
offset += sprintf (buffer + offset, " even more");
printf ("[%s]",buffer);
请注意,为简洁起见,此实现省略了对 realloc 和 snprintf 的检查。它还重复格式字符串和参数。以下函数解决了这些缺点:
int append_buffer(char **buffer, int *offset, const char *format, ...)
{
va_list args;
int len;
va_start(args, format);
len = vsnprintf(NULL, 0, format, args);
if (len < 0) {
perror("vsnprintf failed");
return 0;
}
va_end(args);
char *tmp = realloc(*buffer, *offset + len + 1);
if (!tmp) {
perror("realloc failed");
return 0;
}
*buffer = tmp;
va_start(args, format);
*offset = vsprintf(*buffer + *offset, format, args);
if (len < 0) {
perror("vsnprintf failed");
return 0;
}
va_end(args);
return 1;
}
然后你可以这样调用:
char *buffer = NULL;
int offset = 0;
int rval;
rval = append_buffer(&buffer, &offset, "%d plus %d is %d", 5, 3, 5+3);
if (!rval) return 1;
rval = append_buffer(&buffer, &offset, " and %d minus %d is %d", 6, 3, 6-3);
if (!rval) return 1;
rval = append_buffer(&buffer, &offset, " even more");
if (!rval) return 1;
printf ("[%s]",buffer);
free(buffer);