studio - visual basic net samples
snprintf y Visual Studio 2010 (6)
Tengo la mala suerte de estar atrapado usando VS 2010 para un proyecto y me di cuenta de que el siguiente código aún no se compila con el compilador que no cumple con los estándares:
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
char buffer[512];
snprintf(buffer, sizeof(buffer), "SomeString");
return 0;
}
(falla la compilación con el error: C3861: ''snprintf'': identificador no encontrado)
Recuerdo que este es el caso de VS 2005 y estoy sorprendido de ver que todavía no se ha solucionado.
¿Alguien sabe si Microsoft tiene algún plan para mover sus bibliotecas estándar de C al año 2010?
Creo que el equivalente de Windows es sprintf_s
Intenté el código de @Valentin Milea pero tengo errores de infracción de acceso. Lo único que funcionó para mí fue la implementación de Insane Coding: http://asprintf.insanecoding.org/
Específicamente, estaba trabajando con el código heredado de VC ++ 2008. De la implementación de Insane Coding (se puede descargar desde el enlace de arriba), utilicé tres archivos: asprintf.c
, asprintf.h
y vasprintf-msvc.c
. Otros archivos fueron para otras versiones de MSVC.
[EDITAR] Para completar, sus contenidos son los siguientes:
asprintf.h:
#ifndef INSANE_ASPRINTF_H
#define INSANE_ASPRINTF_H
#ifndef __cplusplus
#include <stdarg.h>
#else
#include <cstdarg>
extern "C"
{
#endif
#define insane_free(ptr) { free(ptr); ptr = 0; }
int vasprintf(char **strp, const char *fmt, va_list ap);
int asprintf(char **strp, const char *fmt, ...);
#ifdef __cplusplus
}
#endif
#endif
asprintf.c:
#include "asprintf.h"
int asprintf(char **strp, const char *fmt, ...)
{
int r;
va_list ap;
va_start(ap, fmt);
r = vasprintf(strp, fmt, ap);
va_end(ap);
return(r);
}
vasprintf-msvc.c:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "asprintf.h"
int vasprintf(char **strp, const char *fmt, va_list ap)
{
int r = -1, size = _vscprintf(fmt, ap);
if ((size >= 0) && (size < INT_MAX))
{
*strp = (char *)malloc(size+1); //+1 for null
if (*strp)
{
r = vsnprintf(*strp, size+1, fmt, ap); //+1 for null
if ((r < 0) || (r > size))
{
insane_free(*strp);
r = -1;
}
}
}
else { *strp = 0; }
return(r);
}
Uso (parte de test.c
provisto por Insane Coding):
#include <stdio.h>
#include <stdlib.h>
#include "asprintf.h"
int main()
{
char *s;
if (asprintf(&s, "Hello, %d in hex padded to 8 digits is: %08x/n", 15, 15) != -1)
{
puts(s);
insane_free(s);
}
}
Otro reemplazo seguro de snprintf()
y vsnprintf()
es provisto por ffmpeg. Puede consultar la fuente aquí (sugerido).
Si no necesita el valor de retorno, también puede definir snprintf como _snprintf_s
#define snprintf(buf,len, format,...) _snprintf_s(buf, len,len, format, __VA_ARGS__)
snprintf
no es parte de C89. Es estándar solo en C99. Microsoft no tiene un plan compatible con C99 .
(¡Pero también es estándar en C ++ 0x ...!)
Vea otras respuestas a continuación para una solución alternativa.
Relato breve: Microsoft finalmente implementó snprintf en Visual Studio 2015. En versiones anteriores, puede simularlo de la siguiente manera.
Versión larga:
Aquí está el comportamiento esperado para snprintf:
int snprintf( char* buffer, std::size_t buf_size, const char* format, ... );
Escribe a lo sumo
buf_size - 1
caracteres en un búfer. La cadena de caracteres resultante terminará con un carácter nulo, a menos quebuf_size
sea cero. Sibuf_size
es cero, no se escribe nada y elbuffer
puede ser un puntero nulo. El valor de retorno es la cantidad de caracteres que se han escrito suponiendo unbuf_size
ilimitado, sin contar el carácter nulo de terminación.
Las versiones anteriores a Visual Studio 2015 no tuvieron una implementación conforme. En su lugar, hay extensiones no estándar como _snprintf()
(que no escribe null-terminator en desbordamiento) y _snprintf_s()
(que puede imponer la terminación nula, pero devuelve -1 en desbordamiento en lugar de la cantidad de caracteres que han sido escritos).
Sugerencia de respaldo para VS 2005 y posteriores:
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf c99_snprintf
#define vsnprintf c99_vsnprintf
__inline int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
{
int count = -1;
if (size != 0)
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
if (count == -1)
count = _vscprintf(format, ap);
return count;
}
__inline int c99_snprintf(char *outBuf, size_t size, const char *format, ...)
{
int count;
va_list ap;
va_start(ap, format);
count = c99_vsnprintf(outBuf, size, format, ap);
va_end(ap);
return count;
}
#endif