sprintf() sans espace nul de fin en C

Existe-t-il un moyen d'utiliser la fonction C sprintf() sans ajouter un caractère '' à la fin de sa sortie? J'ai besoin d'écrire du texte formaté au milieu d'une chaîne de largeur fixe.

33
demandé sur zaratustra 2008-12-10 21:29:24

7 réponses

Il N'y a aucun moyen de dire à sprintf() de ne pas écrire un null final. Ce que vous pouvez faire est d'utiliser sprintf() pour écrire une chaîne temporaire, et puis quelque chose comme strncpy() pour copier uniquement les octets que vous voulez.

37
répondu Greg Hewgill 2008-12-10 18:44:19

Sprintf renvoie la longueur de la chaîne écrite (sans compter le terminal nul), vous pouvez l'utiliser pour savoir où se trouvait le terminal nul, et changer le caractère du terminal nul en autre chose (c'est-à-dire un espace). Ce serait plus efficace que d'utiliser strncpy.

 unsigned int len = sprintf(str, ...);
 str[len] = '<your char here>';
23
répondu Doug T. 2008-12-10 21:11:59

Vous ne pouvez pas faire cela avec sprintf (), mais vous Pouvez Être capable de le faire avec snprintf (), en fonction de votre plate-forme.

Vous devez savoir combien de caractères vous remplacez (mais comme vous les mettez au milieu d'une chaîne, vous le savez probablement de toute façon).

Cela fonctionne parce que certaines implémentations de snprintf () ne garantissent pas qu'un caractère de terminaison est écrit-probablement pour la compatibilité avec des fonctions comme stncpy ().

char message[32] = "Hello 123, it's good to see you.";

snprintf(&message[6],3,"Joe");

Après cela, "123" est remplacé par "Joe".

Sur les implémentations où snprintf () garantit une terminaison nulle même si la chaîne est tronquée, cela ne fonctionnera pas. Donc, si la portabilité du code est une préoccupation, vous devriez éviter cela.

La Plupart des versions Windows de snprintf() présentent ce comportement.

Mais, MacOS et BSD (et peut-être linux) semblent toujours NULL-terminate.

4
répondu Roddy 2009-02-04 16:04:11

Vous pouvez également utiliser votre chaîne de largeur fixe comme une chaîne de format comme ceci:

char my_fixed_width_string_format[] = "need 10 chars starting here: %10s";
char my_fixed_width_string[40];
char string_to_print[] = "abcdefghijklmnop";
sprintf(my_fixed_width_string, my_fixed_width_string_format, string_to_print;
printf(my_fixed_width_string);

Devrait donner

Besoin de 10 caractères commençant ici: abcdefghij

2
répondu Nathan Fellman 2008-12-11 07:52:24

Puisque vous écrivez dans une zone fixe, vous pouvez le faire comme ceci:

// pointer to fixed area we want to write to
char* s;

// number of bytes needed, not including the null
int r = snprintf(0, 0, <your va_args here>);

// char following the last char we will write - null goes here
char c = s[r + 1];

// do the formatted write
snprintf(s, r + 1, <your_va_args here>);

// replace what was overwritten
s[r + 1] = c;
0
répondu Todd Freed 2012-07-03 23:01:47

En fait, cet exemple n'ajoutera pas de valeur null si vous utilisez snprintf:

char name[9] = "QQ40dude";  
unsigned int i0To100 = 63;  
_snprintf(&name[2],2,"%d",i0To100);  
printf(name);// output will be: QQ63dude  
0
répondu yan bellavance 2015-02-21 18:26:33

Regardez ici: http://en.wikipedia.org/wiki/Printf

Printf ("%.*s", 3, "abcdef") entraînera l'impression de" abc "

-2
répondu nir 2010-10-04 13:38:54