这是我在Stack Overflow上面写的一篇答案,很长,都可以做一个博文了。https://stackoverflow.com/questions/40159892/using-asprintf-on-windows/63317479#63317479
VC6 C语言比较老旧,我摸索了出来一个可以用的asprintf实现。
For those with a higher version of MSVC compiler (like you're using VS2010) or those using C++ instead of C, it's easy. You can use the va_list
implementation in another answer here. It's great.
If you're using a GCC-based/-like compiler (like clang, cygwin, MinGW, TDM-GCC etc.), there should be one asprintf
already, I don't know. If not, you can use the va_list
implementation in another answer here.
An VC6 C Implementation (not C++)
Yes, all of the "multi-platform" answers don't support VC6. You have to use this.
(maybe for Turbo C, lcc and any older ones too)
You can't. You have to:
-
Guess a buffer size yourself.
-
Make a buffer that is large enough (which is not easy), then you can get a correct buffer size.
If you choose this, I have make a handy implementation for VC6 C language, based on the va_list
implement in another answer.
For those with a higher version of MSVC compiler (like you're using VS2010) or those using C++ instead of C, it's easy. You can use the va_list
implementation in another answer here. It's great.
If you're using a GCC-based/-like compiler (like clang, cygwin, MinGW, TDM-GCC etc.), there should be one asprintf
already, I don't know. If not, you can use the va_list
implementation in another answer here.
An VC6 C Implementation (not C++)
Yes, all of the "multi-platform" answers don't support VC6. You have to use this.
(maybe for Turbo C, lcc and any older ones too)
You can't. You have to:
-
Guess a buffer size yourself.
-
Make a buffer that is large enough (which is not easy), then you can get a correct buffer size.
If you choose this, I have make a handy implementation for VC6 C language, based on the va_list
implement in another answer.
// #include <stdio.h> /* for _vsnprintf */
// No, you don't need this
#include <stdlib.h> /* for malloc */
#include <stdarg.h> /* for va_* */
#include <string.h> /* for strcpy */
// Note: If it is not large enough, there will be fine
// Your program will not crash, just your string will be truncated.
#define LARGE_ENOUGH_BUFFER_SIZE 256
int vasprintf(char **strp, const char *format, va_list ap)
{
char buffer[LARGE_ENOUGH_BUFFER_SIZE] = { 0 }, *s;
// If you don't initialize it with { 0 } here,
// the output will not be null-terminated, if
// the buffer size is not large enough.
int len,
retval = _vsnprintf(buffer, LARGE_ENOUGH_BUFFER_SIZE - 1, format, ap);
// if we pass LARGE_ENOUGH_BUFFER_SIZE instead of
// LARGE_ENOUGH_BUFFER_SIZE - 1, the buffer may not be
// null-terminated when the buffer size if not large enough
if ((len = retval) == -1) // buffer not large enough
len = LARGE_ENOUGH_BUFFER_SIZE - 1;
// which is equivalent to strlen(buffer)
s = malloc(len + 1);
if (!s)
return -1;
strcpy(s, buffer);
// we don't need to use strncpy here,
// since buffer is guranteed to be null-terminated
// by initializing it with { 0 } and pass
// LARGE_ENOUGH_BUFFER_SIZE - 1 to vsnprintf
// instead of LARGE_ENOUGH_BUFFER_SIZE
*strp = s;
return retval;
}
int asprintf(char **strp, const char *format, ...)
{
va_list ap;
int retval;
va_start(ap, format);
retval = vasprintf(strp, format, ap);
va_end(ap);
return retval;
}
int main(void)
{
char *s;
asprintf(&s