À l'aide de snprintf dans une application multiplate-forme
Je suis en train d'écrire un programme C qui devrait être compilé avec tous les principaux compilateurs. Je suis actuellement en développement sur GCC sur une machine linux et de compiler sur MSVC avant de valider le code. Pour faire de la cross-compilation facile, je suis de la compilation avec -ansi
et -pedantic
drapeaux. Cela a bien fonctionné jusqu'à ce que j'ai commencé à utiliser snprintf
qui n'est pas disponible dans la norme C89. GCC permet de compiler sans le -ansi
switch, mais MSVC échouera toujours comme il n'a pas de support C99.
J'ai donc fait quelque chose comme,
#ifdef WIN32
#define snprintf sprintf_s
#endif
Cela fonctionne bien parce que snprintf
et sprintf_s
a les mêmes signatures. Je me demande est-ce la bonne démarche?
snprintf
standard pour tout C dans n'importe quelle plateforme?pas de.
snprintf
fait partie du standard C99. MSVC n'ont pas de C99 de mise en œuvre.sprintf_s
n'est pas équivalent. snprintf
renvoie le nombre de caractères qui aurait été écrit, alors que sprintf_s
retourne -1 en cas de troncation. Voir cette discussion.Voir la réponse de la poste similaire lien
OriginalL'auteur Navaneeth K N | 2010-10-20
Vous devez vous connecter pour publier un commentaire.
Pas. Votre approche est vouée à l'échec.
sqrt
etcos
ont le même prototype. Pensez-vous que vous pouvez échanger dans un programme et d'obtenir le même comportement d'avant /après le changement?Vous devriez écrire votre propre
snprintf
, ou de télécharger une mise en œuvre à partir de l'internet (google est votre ami) et de l'utiliser à la fois sous Linux et Windows.Cette réponse n'est pas utile. La question d'une manière différente: Depuis snprintf et sprintf_s ont la même signature, ils ont également les mêmes fonctionnalités ? Votre réponse dit en gros: je ne sais pas.
OriginalL'auteur pmg
J'ai trouvé cette sur l'utilisation de
_snprintf()
comme une alternative, et les pièges impliqués si le dépassement de la mémoire tampon de protection déclenche réellement. De ce que j'ai pu voir d'un rapide coup d'œil, semblable mises en garde s'appliquent àsprintf_s
.Oh, et n'oubliez pas d'envoyer un mail à Microsoft en exigeant qu'ils appuyer les normes linguistiques. (Je sais qu'ils ont déjà annoncé qu'ils n'ont pas de plan à l'appui de C99, mais bougre de toute façon. Ils le méritent.)
Bas de ligne, si vous voulez jouer en toute sécurité, vous devez fournir votre propre
snprintf()
(un wrapper autour de_snprintf()
ousprintf_s()
attraper leur non-standard de comportement) pour MSVC.*printf()
mise en oeuvre est assez grand.En fait complète
printf
mise en œuvre peut être très faible. Normalement je suis d'accord avec votre principe de l'emballage cassé implémentations plutôt que de réimplanter, mais depuis Windows*printf
a également brisé des choses que vous ne pouvez pas facilement enveloppe loin (comme en arrière interprétation de%s
et%ls
dans la grande variantes), je me demande juste si le remplaçant pourrait être la meilleure approche.En fait une autre chose que vous pouvez corriger en même temps c'est MS est inexact de virgule flottante de l'impression.
Un naïfs
*printf()
mise en œuvre peut être très faible. Un on peut devenir tout à fait quelque chose. Ma propre mise en œuvre (certes écrit dans un pas-très-laconique style) a un peu plus de 500 lignes déjà, sans support pour %e, %g, %g, échelle de caractères, ou multi-octets chaînes de format.OriginalL'auteur DevSolar
Votre proposition peut fonctionner que si vous êtes prudent. Le problème est que la fonction se comporter légèrement différentes, si ce n'est pas un problème pour vous, vous êtes bon pour aller, sinon penser à une fonction wrapper:
Différences entre MSVCs
_snprintf
et officiel C99 (gcc,clang)snprintf
:Valeur de retour:
Écrit octets:
Intéressant
%n
subtilité:Si vous utilisez
%n
dans votre code, MSVC laisser non! si elle cesse de l'analyse parce que la taille de la mémoire tampon est à petit, GCC sera toujours écrire le nombre d'octets qui ont été écrits si la mémoire tampon aurait été assez grand.Donc ma proposition serait d'écrire votre propre fonction wrapper
mysnprintf
à l'aide devsnprintf
/_vsnprintf
qui offre les mêmes valeurs de retour et écrit les mêmes octets sur les deux plates-formes (attention:%n
est plus difficile à fixer).OriginalL'auteur eci
Vous pouvez ouvrir le NUL fichier spécial pour MSVC et écrire. Il sera toujours de vous dire combien d'octets sont nécessaires, et de ne pas écrire n'importe quoi. Comme:
Ensuite, vous devez savoir combien d'octets à allouer à utiliser sprintf avec succès.
OriginalL'auteur Paul Humphreys
la réponse la plus complète (vous pouvez l'améliorer si vous le souhaitez), mettre dans un autocollant
inline
et variadic fonctions sont des fonctions C99.est un variadic fonction. Il a été autour depuis un certain temps ... Donc, non, ce n'est pas un C99 plus.
OriginalL'auteur donthaveanaccount