asprintf, aswprintf, vasprintf, vaswprintf

来自cppreference.com
< c‎ | experimental‎ | dynamic
在标头 <stdio.h> 定义
int asprintf( char **restrict strp, const char *restrict fmt, ... );
(1) (动态内存 TR)
int aswprintf( wchar_t **restrict strp, const wchar_t *restrict fmt, ... );
(2) (动态内存 TR)
int vasprintf( char **restrict strp, const char *restrict fmt,
               va_list arg );
(3) (动态内存 TR)
int vaswprintf( wchar_t **restrict strp, const wchar_t *restrict fmt,
                va_list arg );
(4) (动态内存 TR)
1) 类同于 sprintf,但它会如同调用 malloc 那样分配足够大的存储空间,以持有包含该空终止字符的输出,并通过其第一个实参返回指向该存储的指针。当不再需要此存储时,应当将这个指针传递给 free 来予以释放。
2)(1) 相同,但它对宽字符 wchar_t 工作(类同于 swprintf)。
3)(1) 相同,但以 arg 替代可变实参列表,它应以 va_start 宏(以及后续可能的 va_arg 调用)初始化。
4)(3) 相同,但它对宽字符 wchar_t 工作。

参数

strp - char*wchar_t* 的指针,其中包含格式化输出
fmt - printf/wprintf 等相关函数相同的格式字符串
arg - 额外实参,与 vsprintfvswprintf 相同

返回值

所写出的字符数量,分别与 sprintf (1), swprintf (2), vsprintf (3), 和 vswprintf (4) 相同。如果不可能分配内存,或发生某些其他错误,则这些函数将返回 -1,而 strp 的内存则未定义。

注解

这些函数是 GNU 扩展,而非 C 或 POSIX 函数。它们在 *BSD 下也可用。FreeBSD 的实现在错误发生时会将 strp 设为 NULL

函数 vasprintfvaswprintf 并不调用 va_end 宏。

示例

可在 clang 上测试 (C11)

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
 
void test(const char *fmt, ...)
{
    char* dyn_buf;
 
    printf("Demo asprintf:\n");
    const int written_1 = asprintf(&dyn_buf, "%s", fmt);
    printf("dyn_buf: \"%s\"; %i chars were written\n", dyn_buf, written_1);
    free(dyn_buf);
 
    printf("Demo vasprintf:\n");
    va_list args;
    va_start(args, fmt);
    const int written_2 = vasprintf(&dyn_buf, fmt, args);
    va_end(args);
    printf("dyn_buf: \"%s\"; %i chars were written\n", dyn_buf, written_2);
    free(dyn_buf);
}
 
int main(void)
{
    test("Testing... %d, %d, %d", 1, 2, 3);
}

输出:

Demo asprintf:
dyn_buf: "Testing... %d, %d, %d"; 21 chars were written
Demo vasprintf:
dyn_buf: "Testing... 1, 2, 3"; 18 chars were written