Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Equivalent printf ostream

17 réponses
Avatar
Plotark
Bonjour a tous,

J'aimerais ecrire en c++ l'equivalent de
printf("%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", u.time_low,
u.time_mid,u.time_hi_and_version,
u.clock_seq_hi_and_reserved,u.clock_seq_low);

Je suis sous visual c++.

Quelqu'un sait-il comment faire pour remplacer tous les formattages %x.x?

Plotark

7 réponses

1 2
Avatar
Samuel Krempp
le Wednesday 07 April 2004 09:29, écrivit :
Tu en es sûr. Il me semblait qu'il y en avait qu'il ne comprenait pas,
et que la précision sur un entier en était un. (Je ne suis pas sûr. je
ne l'ai pas sous la main pour vérifier.)


effectivement pour boost::format, un paramètre de précision est passé à
setprecision, même avec %d ou %x, ce qui n'a pas d'effet pour des
formattages d'entiers.

à un moment j'envisageais de rajouter 4-5 lignes de code pour me rapprocher
du comportement de printf, mais j'ai pas reçu de courriels pour
boost::format à ce propos alors j'imagine que ça n'intéresse personne pour
l'instant.
Personnellement si j'avais besoin de forcer une longueur maximale de chaine
formattée, j'ajouterais alors un signe qui marque les cas de troncation, et
je metterais ça dans une fonction :

std::string trunc_and_show(std::string s, int max,
char trunc_mark = '>' ) {
if(s.size() > max) {
s.resize(max-1);
s.append(trunc_mark);
}
return s;
}

on peut modifier pour passer s par const& pour éviter toute copie dans le
cas size<=max si c'est important.

Faire la troncation comme ça me semble plus utile que la troncation
directement dans printf..


enfin bon, pour supporter la syntaxe printf autant que possible, je vais
ptetre ajouter ça tot ou tard.

--
Sam

Avatar
kanze
Samuel Krempp wrote in message
news:<4073da75$0$17598$...
le Wednesday 07 April 2004 09:29, écrivit :
Tu en es sûr. Il me semblait qu'il y en avait qu'il ne comprenait
pas, et que la précision sur un entier en était un. (Je ne suis pas
sûr. je ne l'ai pas sous la main pour vérifier.)


effectivement pour boost::format, un paramètre de précision est passé
à setprecision, même avec %d ou %x, ce qui n'a pas d'effet pour des
formattages d'entiers.

à un moment j'envisageais de rajouter 4-5 lignes de code pour me
rapprocher du comportement de printf, mais j'ai pas reçu de courriels
pour boost::format à ce propos alors j'imagine que ça n'intéresse
personne pour l'instant.


En effet, il y a certainement de choses plus importantes.

Personnellement si j'avais besoin de forcer une longueur maximale de
chaine formattée, j'ajouterais alors un signe qui marque les cas de
troncation, et je metterais ça dans une fonction :


Attention, la précision dans un entier ne tronque pas. En fait, la
signification de la précision dans printf dépend du type et de la
spécification du formattage :

flottant :
Selon le format : pour %e et %f, donne le nombre de chiffres après
le décimal, pour un %g, le nombre de chiffres totaux (dans la
mantisse). Rémarque bien que quand %g formatte comme un %e, la même
précision donne un chiffre de plus en %e (et que quand le %g
formatte comme un %f, il n'y a aucun rapport immédiate entre le
nombre de chiffres dans les deux).

entier :
La précision donne le nombre minimum de chiffres à générer. Le
défaut est 1, ce qui donne "0" pour 0, mais on peut en passer 0 (ce
qui donne une chaîne vide pour 0) ou plus. Donc, quelque chose comme
"%8.4d" de 42 donne " 0042".

chaîne de caractères :
La précision spécifie le nombre maximum de caractères à prendre de
la chaîne. AMHA, ce n'est pas si utile avec std::string -- je peux
toujours passer un s.substr( 0, n ), pour n'en avoir que n au
maximum. Avec des char const*, ça peut être utile.

[...]
enfin bon, pour supporter la syntaxe printf autant que possible, je
vais ptetre ajouter ça tot ou tard.


Comme j'ai dit, je l'ai fais moi-même plutôt par esprit de défi. Je ne
crois pas que ce soit si essentiel. Si tu as du temps, et tu ne sais
quoi pas en faire, d'accord, mais autrement...

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Samuel Krempp
le Wednesday 07 April 2004 16:29, écrivit :

Attention, la précision dans un entier ne tronque pas. En fait, la
signification de la précision dans printf dépend du type et de la
spécification du formattage :


ah oui t'as raison, dans mon souvenir c'était une histoire de troncation..
auquel cas ça rentre à peu pres dans le meme cadre que la troncation pour
les chaines de caracs, qui est implémentée dans boost::format..

là c'est une longueur minimale préalable au padding, ce qui demande tout un
truc juste pour ça.

entier :
La précision donne le nombre minimum de chiffres à générer. Le
défaut est 1, ce qui donne "0" pour 0, mais on peut en passer 0 (ce
qui donne une chaîne vide pour 0) ou plus. Donc, quelque chose comme
"%8.4d" de 42 donne " 0042".


..

Comme j'ai dit, je l'ai fais moi-même plutôt par esprit de défi. Je ne
crois pas que ce soit si essentiel. Si tu as du temps, et tu ne sais
quoi pas en faire, d'accord, mais autrement...


c'est probablement ce que je m'étais dit aussi le jour où j'ai envisagé de
le faire :)

--
Sam

Avatar
Loïc Joly
wrote:

(Mais si j'en avais besoin, j'avoue que je
créerais des manipulateurs propres, du genre ToCLabel et ToCPageNumber,
afin de pouvoir écrire :

std::cout
<< ToCLabel( 40 ) << title[ i ]
<< ToCPageNumber( 2 ) << page[ i ]
<< 'n' ;

AMHA, c'est bien plus lisible, et en dérivant de GB_StateSavingManip, ce
n'est vraiment que peu de code.


J'hésite pour ma part souvent entre une solution comme celle ci ou une
solution du style :
Label l = 40;
PageNumber p = 2;
sdt::cout << setw(40) << l << setw(2) << p << 'n';

Ou encore une solution :

Label l = 40;
PageNumber p = 2;
sdt::cout << l.toString(40) << p.toString(2) << 'n';


--
Loïc

Avatar
kanze
Loïc Joly wrote in message
news:<c51jek$gf7$...
wrote:

(Mais si j'en avais besoin, j'avoue que je
créerais des manipulateurs propres, du genre ToCLabel et ToCPageNumber,
afin de pouvoir écrire :

std::cout
<< ToCLabel( 40 ) << title[ i ]
<< ToCPageNumber( 2 ) << page[ i ]
<< 'n' ;

AMHA, c'est bien plus lisible, et en dérivant de
GB_StateSavingManip, ce n'est vraiment que peu de code.


J'hésite pour ma part souvent entre une solution comme celle ci ou une
solution du style :

Label l = 40;
PageNumber p = 2;
sdt::cout << setw(40) << l << setw(2) << p << 'n';

Ou encore une solution :

Label l = 40;
PageNumber p = 2;
sdt::cout << l.toString(40) << p.toString(2) << 'n';


Tu veux dire plutôt quelque chose du genre :

std::cout << std::setw( 40 ) << ToCLabel( title[ i ] )
<< std::setw( 2 ) << ToCPageNumber( page[ i ] )
<< 'n' ;

non ? Où ToCLabel et ToCPageNumber sont des classe « wrapper » qui
n'existe que pour des motifs de formattage, quelque chose du genre :

class ToCLabel
{
public:
ToCLabel( std::string const& label )
: myLabel( label )
{
}
friend std::ostreamd& operator<<( std::ostream&, ToCLabel const& ) ;
private :
std::string myLabel ;
} ;

std::ostream&
operator<<( std::ostream& dest, ToCLabel const& source )
{
IOSave tmp( dest ) ;
dest << std::left << setfill( '.' ) << source + ' ' ;
return dest ;
}

C'est aussi une solution. La différence est largement une question de
goût. Ou de contexte. J'aime bien des manipulateurs comme FFmt( w, p ),
pour formatter comme %w.pf, tandis que j'ai bien une classe
ParsableString pour mettre une chaîne en '"', avec des séquences avec
'' pour les caractères spéciaux. Globalement, je crois préférer les
manipulateurs quand il s'agit pûrement du formattage visuel, et une
classe wrapper pour des cas plus complexe. (Ma classe ParsableString
implémente un operator>> aussi, par exemple. Il définit une forme
d'écrire une chaîne arbitraire de caractères qu'il peut ensuite rélire,
sans perte d'information. Et que j'y pense, je crois que ce qu'il me
faudrait, c'est plutôt un ParseableStream, avec des opérateurs<< et >>
templatés, avec des spécialisations pour std::string, char const* et les
types flottants.)

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Arnaud Meurgues
wrote:

class ToCLabel
{
public:
ToCLabel( std::string const& label )
: myLabel( label )
{
}
friend std::ostreamd& operator<<( std::ostream&, ToCLabel const& ) ;
private :
std::string myLabel ;
} ;

std::ostream&
operator<<( std::ostream& dest, ToCLabel const& source )
{
IOSave tmp( dest ) ;
dest << std::left << setfill( '.' ) << source + ' ' ;


c'est pas plutôt source.myLabel, là ?

return dest ;
}


--
Arnaud
(Supprimez les geneurs pour me répondre)

Avatar
kanze
Arnaud Meurgues wrote in message
news:<40751fc0$0$26423$...
wrote:

class ToCLabel
{
public:
ToCLabel( std::string const& label )
: myLabel( label )
{
}
friend std::ostreamd& operator<<( std::ostream&, ToCLabel const& ) ;
private :
std::string myLabel ;
} ;

std::ostream&
operator<<( std::ostream& dest, ToCLabel const& source )
{
IOSave tmp( dest ) ;
dest << std::left << setfill( '.' ) << source + ' ' ;


c'est pas plutôt source.myLabel, là ?


Tout à fait.

return dest ;
}



--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


1 2