Participer au site avec un Tip
Rechercher
 

Améliorations / Corrections

Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.

Emplacement :

Description des améliorations :

Vous êtes un professionnel et vous avez besoin d'une formation ? Programmation avec
Le langage C
Voir le programme détaillé

Fonctions vfprintf_s, vprintf_s, vsprintf_s et vsnprintf_s (C11)

Entêtes à inclure

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>   // <cstdio> en C++
#include <stdarg.h>  // <cstdarg> en C++

Fonctions vfprintf_s, vprintf_s, vsprintf_s et vsnprintf_s

int vfprintf_s( FILE * restrict stream, const char * restrict format, va_list arguments );                               // Depuis C11
int vprintf_s( const char * restrict format, va_list arguments );                                                        // Depuis C11
int vsprintf_s( char * restrict buffer, rsize_t bufferSize, const char * restrict format, va_list arguments );           // Depuis C11
int vsnprintf_s( char * restrict buffer, rsize_t bufferSize, const char * restrict format, va_list arguments );          // Depuis C11

Ces fonctions sont les versions basées sur va_list des fonctions sécurisées fprintf_s, printf_s, sprintf_s et snprintf_s. Elles appartiennent à l'annexe K du standard C11, aussi appelée bounds-checking interfaces.

L'annexe K est optionnelle. Une implémentation C11 peut donc ne pas proposer ces fonctions. Pour demander leurs prototypes, vous devez définir la macro __STDC_WANT_LIB_EXT1__ avant l'inclusion des entêtes standards. Vous pouvez ensuite tester la présence de __STDC_LIB_EXT1__.

Comme les fonctions vfprintf, vprintf, vsprintf et vsnprintf, ces variantes reçoivent une liste de paramètres variables déjà capturée dans une variable de type va_list.

Différences avec les versions classiques

Les versions suffixées par _s ajoutent des contrôles d'exécution. Par exemple, elles permettent de détecter certains paramètres invalides, comme un pointeur nul ou une taille de buffer incohérente. En cas de violation d'une contrainte d'exécution, le gestionnaire de contraintes de l'implémentation peut être invoqué.

Les fonctions vsprintf_s et vsnprintf_s reçoivent la taille du buffer via un paramètre de type rsize_t. Cette taille permet à la fonction de vérifier que l'écriture reste compatible avec la zone mémoire disponible.

A propos de restrict

Les prototypes C11 de ces fonctions utilisent le mot clé restrict. Ce mot clé avait déjà été introduit dans C99 et indique que les zones mémoire pointées par les paramètres concernés ne doivent pas se recouvrir. Cela permet de mieux documenter les contraintes d'appel et peut aider le compilateur à optimiser le code.

Exemple de code

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
#define __STDC_WANT_LIB_EXT1__ 1

#include <stdarg.h>
#include <stdio.h>

#ifdef __STDC_LIB_EXT1__

int buildMessage( char * buffer, rsize_t bufferSize, const char * format, ... ) {

    va_list arguments;

    va_start( arguments, format );
    int result = vsnprintf_s( buffer, bufferSize, format, arguments );
    va_end( arguments );

    return result;
}

#endif

int main() {

#ifdef __STDC_LIB_EXT1__
    char buffer[32];

    buildMessage( buffer, sizeof buffer, "Ligne %d : %s", 12, "OK" );
    printf( "%s\n", buffer );
#else
    puts( "Annexe K non disponible sur cette implementation." );
#endif

    return 0;
}
Exemple d'utilisation de vsnprintf_s

Sur une implémentation qui ne propose pas l'annexe K, l'affichage produit sera :

$> gcc -o Sample -Wall Sample.c
$> ./Sample
Annexe K non disponible sur cette implementation.
$>

Sujets connexes

fprintf
printf
snprintf
va_end
va_list
va_start
vfprintf
vprintf
vsnprintf
vsprintf


Vous êtes un professionnel et vous avez besoin d'une formation ? Programmation avec
Le langage C
Voir le programme détaillé