snprintf
, , _snprintf
_snprintf_l
, , _snwprintf
_snwprintf_l
Écrit des données mises en forme dans une chaîne. Des versions plus sécurisées de ces fonctions sont disponibles ; voir , , _snwprintf_s
_snprintf_s_l
, _snwprintf_s_l
._snprintf_s
Syntaxe
int snprintf(
char *buffer,
size_t count,
const char *format [,
argument] ...
);
int _snprintf(
char *buffer,
size_t count,
const char *format [,
argument] ...
);
int _snprintf_l(
char *buffer,
size_t count,
const char *format,
_locale_t locale [,
argument] ...
);
int _snwprintf(
wchar_t *buffer,
size_t count,
const wchar_t *format [,
argument] ...
);
int _snwprintf_l(
wchar_t *buffer,
size_t count,
const wchar_t *format,
_locale_t locale [,
argument] ...
);
template <size_t size>
int _snprintf(
char (&buffer)[size],
size_t count,
const char *format [,
argument] ...
); // C++ only
template <size_t size>
int _snprintf_l(
char (&buffer)[size],
size_t count,
const char *format,
_locale_t locale [,
argument] ...
); // C++ only
template <size_t size>
int _snwprintf(
wchar_t (&buffer)[size],
size_t count,
const wchar_t *format [,
argument] ...
); // C++ only
template <size_t size>
int _snwprintf_l(
wchar_t (&buffer)[size],
size_t count,
const wchar_t *format,
_locale_t locale [,
argument] ...
); // C++ only
Paramètres
buffer
Emplacement de stockage pour la sortie.
count
Nombre maximal de caractères à écrire. Pour les fonctions qui prennent wchar_t
, il s’agit du nombre maximal de caractères larges à écrire.
format
Chaîne de contrôle de format.
argument
Arguments facultatifs.
locale
Paramètres régionaux à utiliser pour mettre en forme la sortie.
Pour plus d’informations, consultez la syntaxe de spécification de format : printf
et wprintf
les fonctions.
Valeur retournée
Nombre de caractères qui auraient été écrits dans la mémoire tampon s’ils count
étaient ignorés. Le nombre n’inclut pas le caractère de NULL
fin.
Supposons que la longueur de la chaîne de données mise en forme n’inclue len
pas la fin NULL
.
Pour toutes les fonctions, si len < count
, les len
caractères sont stockés dans buffer
, un point de terminaison Null est ajouté et le nombre de caractères écrits, sans inclure la fin NULL
, est retourné.
Les versions de caractères larges de ces fonctions retournent le nombre de caractères larges écrits, sans inclure la fin NULL
.
Pour plus d’informations, consultez le résumé du comportement.
Notes
Depuis le composant UCRT dans Visual Studio 2015 et Windows 10, snprintf
n’est plus identique à _snprintf
. Le snprintf
comportement est désormais conforme aux normes C99. La différence est que si vous n’avez plus de mémoire tampon, snprintf
null met fin à la fin de la mémoire tampon et retourne le nombre de caractères qui auraient été requis, tandis que _snprintf
ne termine pas la mémoire tampon et retourne -1. snprintf()
Inclut également un caractère supplémentaire dans la sortie, car il n’arrête pas la mémoire tampon.
snprintf
et la_snprintf
famille de fonctions formatent et stockentcount
ou moins de caractères dansbuffer
.snprintf
stocke toujours un caractère de finNULL
, tronqué la sortie si nécessaire.- Si
snprintf
elle retourne une valeur >count
- 1, la sortie a été tronquée. - La
_snprintf
famille de fonctions ajoute uniquement un caractère deNULL
fin si la longueur de chaîne mise en forme est strictement inférieure à celle descount
caractères. - Chaque
argument
(le cas échéant) est converti et sorti selon la spécification de format correspondante dansformat
. Le format se compose de caractères ordinaires et a la même forme et la même fonction que l’argumentformat
pourprintf
. Si une copie se produit entre des chaînes qui se chevauchent, le comportement est indéfini.
Résumé du comportement
Pour le tableau suivant :
- Supposons
sizeOfBuffer
que la taille soit la taille debuffer
. Si la fonction prend unechar
mémoire tampon, la taille est en octets. Si la fonction prend unewchar_t
mémoire tampon, la taille spécifie le nombre de mots 16 bits. - Supposons
len
que la taille des données mises en forme soit la taille. Si la fonction prend unechar
mémoire tampon, la taille est en octets. Si la fonction prend unewchar_t
mémoire tampon, la taille spécifie le nombre de mots 16 bits. - Les caractères font référence aux
char
caractères des fonctions qui prennent unechar
mémoire tampon et auxwchar_t
caractères des fonctions qui prennent unewchar_t
mémoire tampon. - Pour plus d’informations sur le gestionnaire de paramètres non valide, consultez Validation des paramètres.
Condition | Comportement | Valeur retournée | errno |
Appelle un gestionnaire de paramètres non valides |
---|---|---|---|---|
Réussite | Écrit les caractères dans la mémoire tampon à l’aide de la chaîne de format spécifiée. | Nombre de caractères écrits. | S/O | Non |
Erreur d’encodage lors de la mise en forme | Si le spécificateur s de chaîne de traitement , S ou , le Z traitement des spécifications de format s’arrête, il NULL est placé au début de la mémoire tampon. |
-1 | EILSEQ (42) |
Non |
Erreur d’encodage lors de la mise en forme | Si le spécificateur c de caractère de traitement ou C , le caractère non valide est ignoré. Le nombre de caractères écrits n’est pas incrémenté pour le caractère ignoré, ni aucune donnée n’est écrite pour elle. Le traitement de la spécification du format se poursuit après avoir ignoré le spécificateur avec l’erreur d’encodage. |
Nombre de caractères écrits, sans inclure la fin NULL . |
EILSEQ (42) |
Non |
buffer == NULL et count != 0 |
Si l’exécution se poursuit après l’exécution du gestionnaire de paramètres non valide, définit errno et retourne une valeur négative. |
-1 | EINVAL (22) |
Oui |
count == 0 |
Nombre de caractères qui auraient été écrits, sans inclure la fin NULL . Vous pouvez utiliser ce résultat pour allouer suffisamment d’espace tampon pour la chaîne et une fin NULL , puis appeler à nouveau la fonction pour remplir la mémoire tampon. |
S/O | Non | |
count < 0 |
Non sécurisé : la valeur est traitée comme non signée, ce qui crée probablement une valeur importante qui entraîne le remplacement de la mémoire qui suit la mémoire tampon. | Nombre de caractères écrits | S/O | Non |
count < sizeOfBuffer et len <= count |
Toutes les données sont écrites et une fin NULL est ajoutée. |
Nombre de caractères écrits, sans inclure la fin NULL . |
S/O | Non |
count < sizeOfBuffer et len > count |
Les premiers count-1 caractères sont écrits suivis d’un terminateur null. |
Le nombre de caractères qui auraient été écrits avait count mis en correspondance le nombre de caractères à générer, sans inclure le terminateur Null. |
S/O | Non |
count >= sizeOfBuffer et len < sizeOfBuffer |
Toutes les données sont écrites avec une fin NULL . |
Nombre de caractères écrits, sans inclure la fin NULL . |
S/O | Non |
count >= sizeOfBuffer et len >= sizeOfBuffer |
Non sécurisé : remplace la mémoire qui suit la mémoire tampon. | Nombre de caractères écrits, sans inclure la fin NULL . |
S/O | Non |
format == NULL |
Aucune donnée n’est écrite. Si l’exécution se poursuit après l’exécution du gestionnaire de paramètres non valide, définit errno et retourne une valeur négative. |
-1 | EINVAL (22) |
Oui |
Pour plus d’informations sur ces codes d’erreur et d’autres codes d’erreur, consultez , , _sys_errlist
errno
et _sys_nerr
._doserrno
Important
Assurez-vous que format
n'est pas une chaîne définie par l'utilisateur. Étant donné que les _snprintf
fonctions ne garantissent pas l’arrêt null, en particulier lorsque la valeur de retour est count
, assurez-vous qu’elles sont suivies par le code qui ajoute le terminateur Null. Pour plus d’informations, consultez Solutions contre les dépassements de mémoire tampon.
À compter de Windows 10 version 2004 (build 19041), la famille de fonctions printf
imprime exactement les nombres à virgule flottante pouvant être représentés en suivant les règles IEEE 754 pour l’arrondi. Dans les versions précédentes de Windows, les nombres à virgule flottante pouvant être représentés exactement qui se terminent par « 5 » sont toujours arrondis à la valeur supérieure. IEEE 754 indique qu’ils doivent être arrondis au chiffre pair le plus proche (également appelé « arrondi du banquier »). Par exemple, printf("%1.0f", 1.5)
et printf("%1.0f", 2.5)
doivent être arrondis à 2. Avant, 1.5 aurait été arrondi à 2 et 2.5 à 3. Ce changement affecte uniquement les nombres représentables avec précision. Par exemple, 2.35 (qui, lorsqu’il est représenté en mémoire, est plus proche de 2.35000000000000008) continue d’être arrondi à la valeur supérieure 2.4. L’arrondi effectué par ces fonctions respecte également le mode d’arrondi à virgule flottante défini par fesetround
. Avant, l’arrondi choisissait toujours le comportement FE_TONEAREST
. Ce changement affecte uniquement les programmes générés à l’aide de Visual Studio 2019 versions 16.2 et ultérieures. Pour utiliser le comportement d’arrondi à virgule flottante héritée, liez avec legacy_stdio_float_rounding.obj
.
_snwprintf
est une version à caractères larges de _snprintf
; les arguments de pointeur de _snwprintf
sont des chaînes à caractères larges. La détection des erreurs _snwprintf
d’encodage peut différer de la détection dans _snprintf
. _snwprintf
, tout comme swprintf
, écrit la sortie dans une chaîne au lieu d'une destination de type FILE
.
Les versions de ces fonctions avec le suffixe _l
sont identiques, sauf qu'elles utilisent les paramètres régionaux passés au lieu des paramètres régionaux du thread actuel.
En C++, ces fonctions ont des surcharges de modèle qui appellent les équivalents plus récents et plus sécurisés. Pour plus d'informations, consultez Sécuriser les surcharges de modèle.
Mappages de routines de texte générique
Routine Tchar.h |
_UNICODE et _MBCS non définis |
_MBCS défini |
_UNICODE défini |
---|---|---|---|
_sntprintf |
_snprintf |
_snprintf |
_snwprintf |
_sntprintf_l |
_snprintf_l |
_snprintf_l |
_snwprintf_l |
Spécifications
Routine | En-tête requis |
---|---|
snprintf , , _snprintf _snprintf_l |
<stdio.h> |
_snwprintf , _snwprintf_l |
<stdio.h> ou <wchar.h> |
Pour plus d’informations sur la compatibilité, consultez Compatibility.
Exemple
// crt_snprintf.c
// compile with: /W3
#include <stdio.h>
#include <stdlib.h>
#if !defined(__cplusplus)
typedef int bool;
const bool true = 1;
const bool false = 0;
#endif
#define FAIL 0 // change to 1 and see what happens
int main(void)
{
char buffer[200];
const static char s[] = "computer"
#if FAIL
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
#endif
;
const char c = 'l';
const int i = 35;
#if FAIL
const double fp = 1e300; // doesn't fit in the buffer
#else
const double fp = 1.7320534;
#endif
/* !subtract one to prevent "squeezing out" the terminal null! */
const int bufferSize = sizeof(buffer)/sizeof(buffer[0]) - 1;
int bufferUsed = 0;
int bufferLeft = bufferSize - bufferUsed;
bool bSuccess = true;
buffer[0] = 0;
/* Format and print various data: */
if (bufferLeft > 0)
{
int perElementBufferUsed = _snprintf(&buffer[bufferUsed],
bufferLeft, " String: %s\n", s ); // C4996
// Note: _snprintf is deprecated; consider _snprintf_s instead
if (bSuccess = (perElementBufferUsed >= 0))
{
bufferUsed += perElementBufferUsed;
bufferLeft -= perElementBufferUsed;
if (bufferLeft > 0)
{
int perElementBufferUsed = _snprintf(&buffer[bufferUsed],
bufferLeft, " Character: %c\n", c ); // C4996
if (bSuccess = (perElementBufferUsed >= 0))
{
bufferUsed += perElementBufferUsed;
bufferLeft -= perElementBufferUsed;
if (bufferLeft > 0)
{
int perElementBufferUsed = _snprintf(&buffer
[bufferUsed], bufferLeft, " Integer: %d\n", i ); // C4996
if (bSuccess = (perElementBufferUsed >= 0))
{
bufferUsed += perElementBufferUsed;
bufferLeft -= perElementBufferUsed;
if (bufferLeft > 0)
{
int perElementBufferUsed = _snprintf(&buffer
[bufferUsed], bufferLeft, " Real: %f\n", fp ); // C4996
if (bSuccess = (perElementBufferUsed >= 0))
{
bufferUsed += perElementBufferUsed;
}
}
}
}
}
}
}
}
if (!bSuccess)
{
printf("%s\n", "failure");
}
else
{
/* !store null because _snprintf doesn't necessarily (if the string
* fits without the terminal null, but not with it)!
* bufferUsed might be as large as bufferSize, which normally is
* like going one element beyond a buffer, but in this case
* subtracted one from bufferSize, so we're ok.
*/
buffer[bufferUsed] = 0;
printf( "Output:\n%s\ncharacter count = %d\n", buffer, bufferUsed );
}
return EXIT_SUCCESS;
}
Output:
String: computer
Character: l
Integer: 35
Real: 1.732053
character count = 69
Voir aussi
E/S de flux
sprintf
, , _sprintf_l
swprintf
, , _swprintf_l
__swprintf_l
fprintf
, , _fprintf_l
fwprintf
, ,_fwprintf_l
printf
, , _printf_l
wprintf
, ,_wprintf_l
scanf
, , _scanf_l
wscanf
, ,_wscanf_l
sscanf
, , _sscanf_l
swscanf
, ,_swscanf_l
vprintf
, fonctions