Je dois sortir une chaîne qui commence par% character (% EE # WD ...) et j'utilise sprintf. Dans plusieurs références, j'ai lu qu'en utilisant un spécificateur% après%, la fonction sprintf renvoie le caractère%.
Mais pour moi, dans différents compilateurs (comme DEV C ++, JDOODLE), le résultat n'est pas ce à quoi je m'attendais et enfin j'ai obtenu le caractère% en répétant le spécificateur% 4 fois!
Quelle est la raison?
Voici le code et les sorties:
#include <stdio.h> int main() { static char Command[10] ; sprintf (Command,"%%%%EE#") ; printf (Command) ; return 0 ; }
4 Réponses :
sprintf (Command,"%%%%EE#") ; printf (Command) ;
En effet, mais ce n'est pas ce qui est imprimé par la ligne next pour la raison expliquée par @xing
oui, bien sûr, printf (commande) obtient le résultat précédent sous forme de format
@ChrisStratton j'ai édité ma réponse, quand quelque chose est sous-entendu j'ai la mauvaise habitude de ne pas le dire dans ma réponse, j'ai du mal à me corriger
%%
vous donnera %
le % E
fait en fait référence à la notation scientifique, c'est pourquoi vous obtenez un nombre et avez besoin de plus %
pour imprimer %E
Seulement parce qu'il est interprété deux fois pour la raison indiquée par @xing. Ce que vous proposez n'est pas vraiment la bonne solution, sauf si l'objectif est de générer par programme une chaîne de format, ce qui, bien que possible , n'est pas ce que l'on souhaite ici, et n'est généralement pas une bonne idée.
Après sprintf (Command, "%% EE #")
, la Command
contiendra % EE #
. Si vous passez maintenant ce contenu à printf
en tant que chaîne de format, le (maintenant) unique %
sera interprété comme un spécificateur de format, recherchant alors un argument flottant. Ceci n'est pas fourni et conduit en fait à un comportement indéfini. Avec sprintf (Command, "%%%% EE #")
, vous "surmontez" ce problème car Command
contiendra %% EE #
alors.
Mais en fait, vous devriez écrire ...
static char Command[10]; strcpy(Command,"%EE#"); printf ("%s",Command);
Ou ...
static char Command[10] = "%EE#"; printf ("%s",Command);
... ou utilisez put ()
ou fputs ()
si vous voulez sortir une chaîne telle quelle, sans engager la machine de formatage.
@JohnBollinger Un bon compilateur émettra le même code efficace pour printf ("% s", Command);
et fputs (Command, stdout);
. IMO, codez pour plus de clarté et laissez le compilateur gérer ces optimisations linéaires.
@chux, je soumets que l'utilisation de fputs (Command, stdout)
au lieu de printf ("% s", Command)
est codant pour plus de clarté. C'est, en fait, mon point.
@JohnBollinger J'ai lu le commentaire en tant que point sur l'efficacité du code, pas la clarté. Ce qui semble le plus clair dans un contexte diffère et dépend du code voisin. IAC, nous convenons que la clarté est un problème déterminant. En général, je trouve aussi fputs ()
meilleur, mais près de nombreuses lignes de code printf ()
non triviales, je trouve printf ("% s ", Command)
plus clair. ... Et attendez-vous à ce que mon compilateur fasse du bon travail.
La transmission du résultat de sprintf
comme premier argument à printf
entraîne sa réinterprétation en tant que chaîne de format. Ainsi, votre chaîne est interprétée comme une chaîne de format une fois pour sprintf
et de nouveau pour printf
. Ne faites pas cela.
Si vous n'avez pas besoin de formatage, imprimez simplement une chaîne avec fputs
, comme dans fputs ("% EE #", stdout);
. ( met
est similaire, mais il ajoute un caractère de nouvelle ligne. fputs
imprime simplement les caractères qui lui sont donnés.)
Si vous avez besoin d'un formatage et pouvez imprimer directement (sans tampon intermédiaire), utilisez printf
; n'utilisez pas sprintf
au préalable.
Si vous avez besoin d'un formatage et que le résultat doit être écrit dans un tampon, utilisez sprintf
et imprimez le tampon avec fputs
, pas printf
.
@xing - ce serait en effet le problème, si vous expliquez un peu plus, cela ferait une excellente réponse
premier sprintf
"%%%% EE #"
->"%% EE #"
. Le deuxième printf car il s'agit de la chaîne de format"%% EE #"
->"% EE #"
. Pour imprimer la chaîne, utilisez à la place. C'est de toute façon beaucoup plus rapide.@xing merci beaucoup. J'ai compris