91 votes

Snprintf () ALWAYS null termine-t-il?

Snprintf est-il toujours nul en terminant le tampon de destination?

En d'autres termes, est-ce suffisant:

 char dst[10];

snprintf(dst, sizeof (dst), "blah %s", somestr);
 

ou devez-vous faire comme ceci, si quelque chose est assez long?

 char dst[10];

somestr[sizeof (dst) - 1] = '\0';
snprintf(dst, sizeof (dst) - 1, "blah %s", somestr);
 

Je suis intéressé à la fois par ce que dit le standard et par ce que pourrait faire une bibliothèque populaire qui n’est pas un comportement standard.

75voto

Martin Ba Points 10243

Comme les autres réponses établir: Il doit:

snprintf ... Écrit les résultats dans une chaîne de caractères de la mémoire tampon. (...) sera terminé par un caractère nul, à moins que buf_size est égale à zéro.

Donc, tout ce que vous avez à prendre soin de est que vous ne passez pas d'un zéro-taille de la mémoire tampon, parce que (évidemment), il ne peut pas écrire de zéro à "nulle part".


Toutefois, méfiez-vous que Microsoft bibliothèque ne dispose pas d' une fonction appelée snprintf , mais, au contraire, a une fonction appelée _snprintf (note trait de soulignement) qui n'ajoute pas une valeur null. Voici les docs:

http://msdn.microsoft.com/en-us/library/2ts7cx93%28v=vs.110%29.aspx

Valeur De Retour

Laissez len être la longueur de la mise en forme des données de la chaîne (pas y compris le valeur null). len et de comptage sont en octets pour les _snprintf, large personnages pour _snwprintf.

  • Si len < count, puis len caractères sont stockés dans la mémoire tampon, une null-terminator est ajouté, et le len est retourné.

  • Si len = count, puis len caractères sont stockés dans la mémoire tampon, non null-terminator est ajouté, et le len est retourné.

  • Si len > le comte, puis de compter les caractères sont stockés dans la mémoire tampon, non null-terminator est ajouté, et une valeur négative est retourné.

(...)

20voto

piotr Points 2826

Selon la page de manuel snprintf (3).

Les fonctions snprintf() et vsnprintf() écrivent au maximum size octets (y compris l'octet nul final ('\ 0')) dans str .

Donc, oui, pas besoin de terminer si size> = 1.

12voto

Jonathan Leffler Points 299946

Selon la norme, à moins que la taille de la mémoire tampon est de 0, vsnprintf() et snprintf() null met fin à sa sortie.

L' snprintf() fonction est équivalent à sprintf(), avec l'ajout de la n de l'argument qui indique la taille de la mémoire tampon visées par s. Si n est égal à zéro, rien ne doit être écrit et s peut être un pointeur null. Sinon, les octets de sortie au-delà de la n-1er doit être éliminé au lieu d'être écrit au tableau, et un octet nul est écrit à la fin des octets effectivement écrits dans le tableau.

Donc, si vous avez besoin de savoir comment grand d'un tampon d'allouer, utiliser une taille de zéro, et vous pouvez alors utiliser un pointeur null en tant que destination. Note que j'ai relié à la POSIX pages, mais ces explicitement dire qu'il n'est pas destiné à être toute divergence entre la Norme C et POSIX où elles couvrent le sol même:

La fonctionnalité décrite sur cette page de référence est aligné avec le C ISO standard. Tout conflit entre les exigences décrites ici et le standard ISO C est involontaire. Ce volume de POSIX.1-2008 date diffère de la norme ISO C standard.

Méfiez-vous de la version Microsoft de vsnprintf(). C'est très certainement se comporte différemment de la norme C version quand il n'y a pas assez d'espace dans la mémoire tampon (elle renvoie -1 si la fonction retourne la longueur requise). Il n'est pas tout à fait clair que la version de Microsoft null met fin à sa sortie en cas d'erreur, alors que le standard C version ne.

Notez également les réponses à Faire, vous utilisez le TR 24731 les fonctions de sécurité? (voir MSDN pour la version Microsoft de l' vsprintf_s()) et Mac solution pour la sécurité des solutions de rechange à la contamination des fonctions de la bibliothèque C standard?

4voto

Art Points 6040

Certaines versions plus anciennes de SunOS faisaient des choses bizarres avec snprintf et n'avaient peut-être pas terminé la sortie avec NUL et avaient des valeurs de retour qui ne correspondaient pas à celles de tout le monde, mais tout ce qui a été publié au cours des 10 dernières années fait ce que C99 dit.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X