2012-02-20 16 views
9

A (muy largo), mientras que hace que regularmente utiliza el siguiente código - de entonces MSVC 6 - para determinar la memoria necesaria para dar formato a una cadena para una función con argumentos variadic:Cálculo del tamaño de un sprintf() búfer

void LogPrint(const char *pszFormat, ...) 
{ 
    int   nBytes; 
    char  *pszBuffer; 
    va_list  args; 

    va_start(args, pszFormat); 
    nBytes = vsnprintf(0, 0, pszFormat, va); 
    va_end(args); 

    // error checking omitted for brevity 
    pszBuffer = new char[nBytes + 1]; 

    va_start(args, pszFormat); 
    vsnprintf(pszBuffer, nBytes, pszFormat, va); 
    va_end(); 

    // ... 
} 

El error obvio que está recibiendo en una versión más reciente de MSVC (estoy usando ahora 2010) es:

advertencia C4996: 'vsnprintf': Esta función o variable pueden ser inseguros. Considere usar vsnprintf_s en su lugar. Para desactivar la desactivación use _CRT_SECURE_NO_WARNINGS. Consulte la ayuda en línea para obtener detalles.

Soy un gran admirador de la opción "tratar advertencias como errores" para cualquier compilador C (++), y obviamente mi compilación falla. Se siente como hacer trampas para simplemente emplear #pragma warning (disable:4996) y seguir con ello.

La alternativa "segura" sugerida vsnprintf_s(), sin embargo, is doomed to return -1 cuando se producen las condiciones de entrada de su predecesor "inseguro".

TL/DR: ¿Hay una manera de poner en práctica el comportamiento esperado de vsnprintf() para devolver la memoria necesaria para cumplir con su tarea usando las nuevas variantes, más seguros de la misma?


EDIT: simplemente definiendo _CRT_SECURE_NO_WARNINGS no se corte; Hay un montón de strcpy() volando alrededor, también. La nueva variante de la cual no está rota, por lo que me gustaría seguir viendo estos.

+0

'vsprintf_s' no solo es m $ solamente (y por lo tanto no es comercial), muchas personas dicen que su único propósito es reforzar el bloqueo de su proveedor, por lo que ha pensado en deshabilitar la sugerencia de reemplazar todo llamadas estándar por _s variantes? – PlasmaHH

+1

@PlasmaHH: C11 contiene las funciones '_s' como recomendaciones en el apéndice opcional K. –

+0

Sí. Yo tengo. Pero como dije, se siente como engañarme. Después de todo, aparte del software de bloqueo de proveedores, alguien debe haber pensado en la función ingeniosa de 'vsnprintf()' antes * de hacer que no esté disponible. –

Respuesta

12

La función que desea mirar es _vscprintf, que "devuelve el número de caracteres que se generarían si la cadena a la que apunta la lista de argumentos fue impreso o enviado a un archivo o tampón utilizando los códigos de formato especificados ". También hay una variante de ancho (_vscwprintf).

Cuestiones relacionadas