 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
KooK Guest
|
Posted: Tue Jul 04, 2006 7:40 pm Post subject: écriture des nombres (formatage de sortie) |
|
|
Bonjour,
Je voudrais écrire les nombres avec un espace tous les 3 chiffres afin
de les rendre plus lisibles. J'ai regardé du coté de setf et setw sans
succès. Suis-je passé à côté ? Quel fonction utiliser ?
exemple :
int main(void)
{
int a = 1000000;
//fonction pour faire afficher 1 000 000
cout << a << endl;
return 0;
}
Si vous savez répondre à la même question en C je suis preneur aussi.
KooK |
|
| Back to top |
|
 |
Olivier Miakinen Guest
|
Posted: Tue Jul 04, 2006 10:26 pm Post subject: Re: écriture des nombres (formatage de sortie) |
|
|
Le 04/07/2006 16:40, KooK a écrit :
| Quote: |
Je voudrais écrire les nombres avec un espace tous les 3 chiffres afin
de les rendre plus lisibles. J'ai regardé du coté de setf et setw sans
succès. Suis-je passé à côté ? Quel fonction utiliser ?
|
J'ai bien ça en PHP, mais bon, je ne suis pas sûr que ça t'intéresse...
| Quote: | exemple :
int main(void)
{
int a = 1000000;
//fonction pour faire afficher 1 000 000
cout << a << endl;
return 0;
}
Si vous savez répondre à la même question en C je suis preneur aussi.
|
J'ai relu toute la doc de printf() et fonctions assimilées sans rien
trouver. Je suppose que tu dois pouvoir t'en sortir avec une fonction
qui transforme le nombre en chaîne de caractères (par sprintf() par
exemple) avant de découper le résultat en tranches.
--
Olivier Miakinen
Troll du plus sage chez les conviviaux : le nouveau venu, avec
son clan, s'infiltre dans les groupes de nouvelles. (3 c.) |
|
| Back to top |
|
 |
Sylvain Guest
|
Posted: Tue Jul 04, 2006 11:16 pm Post subject: Re: écriture des nombres (formatage de sortie) |
|
|
KooK wrote on 04/07/2006 16:40:
| Quote: | Bonjour,
Je voudrais écrire les nombres avec un espace tous les 3 chiffres afin
de les rendre plus lisibles. J'ai regardé du coté de setf et setw sans
succès. Suis-je passé à côté ? Quel fonction utiliser ?
|
pourquoi pas:
ostream& format3(ostream& out, long value)
{
if (value < 1000)
out << value;
else {
register int digit = (int) log10(value);
int divider = (long) pow(10.0, digit - (digit % 3));
long temp = (value / divider) % 1000;
char buff[5];
sprintf(buff, "%i", temp);
out << buff;
for (divider /= 1000; divider > 0; divider /= 1000){
temp = (value / divider) % 1000;
sprintf(buff, " %.03i", temp);
out << buff;
}
}
return out;
}
| Quote: | Si vous savez répondre à la même question en C je suis preneur aussi.
|
ça doit marcher aussi.
Sylvain. |
|
| Back to top |
|
 |
Arnaud Debaene Guest
|
Posted: Tue Jul 04, 2006 11:21 pm Post subject: Re: écriture des nombres (formatage de sortie) |
|
|
"KooK" <bleuf (AT) free (DOT) fr> a écrit dans le message de news:
44aa7d2d$0$31511$626a54ce (AT) news (DOT) free.fr...
| Quote: | Bonjour,
Je voudrais écrire les nombres avec un espace tous les 3 chiffres afin de
les rendre plus lisibles. J'ai regardé du coté de setf et setw sans
succès. Suis-je passé à côté ? Quel fonction utiliser ?
exemple :
int main(void)
{
int a = 1000000;
//fonction pour faire afficher 1 000 000
cout << a << endl;
return 0;
}
|
Il faut utiliser les locales, plus particulièrement le facet numpunct :
class MyNumPunct : public std::numpunct<char>
{
protected:
virtual std::string do_grouping() const
{
return "\3"; //groupes de 3 chiffres. Oui, le formattage de cetet
chaine est stupide.....
}
virtual char do_thousands_sep() const
{
return ' '; //séparés par espace
}
};
int main()
{
MyNumPunct* punct=new MyNumPunct(); //will be destroyed by the locale
destructor
//create a new locale based on cout, but using our specific numpunct
std::locale loc(std::cout.getloc (), punct);
std::cout.imbue (loc);
std::cout<<2123456789<<std::endl;
}
cf
http://www.roguewave.com/support/docs/leif/sourcepro/html/stdlibref/num-put.html
pour plus de détails.
Arnaud
MVP - VC |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Wed Jul 05, 2006 9:12 am Post subject: Re: écriture des nombres (formatage de sortie) |
|
|
Sylvain wrote:
| Quote: | KooK wrote on 04/07/2006 16:40:
Bonjour,
Je voudrais écrire les nombres avec un espace tous les 3 chiffres afin
de les rendre plus lisibles. J'ai regardé du coté de setf et setw sans
succès. Suis-je passé à côté ? Quel fonction utiliser ?
pourquoi pas:
ostream& format3(ostream& out, long value)
{
if (value < 1000)
out << value;
else {
register int digit = (int) log10(value);
int divider = (long) pow(10.0, digit - (digit % 3));
long temp = (value / divider) % 1000;
char buff[5];
sprintf(buff, "%i", temp);
out << buff;
for (divider /= 1000; divider > 0; divider /= 1000){
temp = (value / divider) % 1000;
sprintf(buff, " %.03i", temp);
out << buff;
}
}
return out;
}
Si vous savez répondre à la même question en C je suis preneur aussi.
ça doit marcher aussi.
|
Pourquoi faire simple quand on peut faire compliqué, n'est-ce
pas ? Pour le C++, Arnaud a donné la bonne réponse. En C, c'est
moins évident, mais dans les deux cas, la première chose à
faire, c'est de voir s'il n'y a pas un locale tout fait qui fait
ce que tu veux. Sinon, en C++, on en crée un, comme a expliqué
Arnaud. En C, il faudrait voir au niveau de système comment en
installer un ; C n'offre pas de possibilités d'en créer un à
l'intérieur du programme. (Posix et Linux, par exemple,
fournissent une commande « localedef » pour le faire. En
revanche, en général il faut être root pour pouvoir le faire.)
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
Guest
|
Posted: Wed Jul 05, 2006 8:59 pm Post subject: Re: écriture des nombres (formatage de sortie) |
|
|
kanze a écrit :
| Quote: |
Pourquoi faire simple quand on peut faire compliqué, n'est-ce
pas ? Pour le C++, Arnaud a donné la bonne réponse.
|
J'ai un petit doute sur la réponse que j'ai donné magré tout :
int main()
{
MyNumPunct* punct=new MyNumPunct(); //will be destroyed by the
locale
destructor
//create a new locale based on cout, but using our specific numpunct
std::locale loc(std::cout.getloc (), punct);
.....
Le fait que la locale appelle delete sur punct dans son destructeur, je
l'observe bien dans mon implémentation (VC2005), mais je n'ai pas
réussi à trouver de documentation "officielle" (ni dans le Josuttis,
ni dans la norme) qui spécifie clairement que c'est un comportement
normal, et comme je trouve que c'est une API un peu bizarre, je me
demande s'il n'y a pas un loup...
Ceci-dit, toute l'API des locale est "bizarre" Si quelqu'un a une
explication claire sur les règles de gestion des durées de vie des
facets par rapport aux locales, je suis preneur....
Arnaud
MVP - VC |
|
| Back to top |
|
 |
Franck Branjonneau Guest
|
Posted: Wed Jul 05, 2006 9:50 pm Post subject: Re: écriture des nombres (formatage de sortie) |
|
|
adebaene@club-internet.fr écrivait:
| Quote: | Le fait que la locale appelle delete sur punct dans son destructeur, je
l'observe bien dans mon implémentation (VC2005), mais je n'ai pas
réussi à trouver de documentation "officielle" (ni dans le Josuttis,
ni dans la norme) qui spécifie clairement que c'est un comportement
normal, et comme je trouve que c'est une API un peu bizarre, je me
demande s'il n'y a pas un loup...
|
22.1.1.2
| Quote: | Ceci-dit, toute l'API des locale est "bizarre" Si quelqu'un a une
explication claire sur les règles de gestion des durées de vie des
facets par rapport aux locales, je suis preneur....
|
22.1.1.2 ?
--
Franck Branjonneau |
|
| Back to top |
|
 |
Sylvain Guest
|
Posted: Thu Jul 06, 2006 3:27 am Post subject: Re: écriture des nombres (formatage d e sortie) |
|
|
kanze wrote on 05/07/2006 10:29:
| Quote: |
Pourquoi faire simple quand on peut faire compliqué, n'est-ce pas?
|
tu as raison, j'aurais du écrire:
ostream& format3(ostream& out, long value){
register int digit = (int) log10(value);
long divider = (long) pow(10.0, digit - (digit % 3));
out << ((value / divider) % 1000);
for (divider /= 1000; divider > 0; divider /= 1000){
char buff[5];
sprintf(buff, " %.03i", (value / divider) % 1000);
out << buff;
}
return out;
}
(je laisse le "if (value<0){ out <<'-'; value = -value; }" à la
discrétion du lecteur).
| Quote: | Pour le C++, Arnaud a donné la bonne réponse. En C, c'est
moins évident,
|
en C++ comme en C, qu'est-ce que ostream et string peuvent utiliser
d'autre que sprintf ?? "ils" ont raison, coder un subset sur les mêmes
bases est mal ? intéressant ...
une chose plus intéressante aurait été de préférer une fonction
retournant un std::string afin de l'utiliser dans un chainage de <<
(tout en permettant le formatage à destination d'un string (basic_string
n'héritant pas de ostream) ou, indirectement, d'un ostream).
| Quote: | mais dans les deux cas, la première chose à
faire, c'est de voir s'il n'y a pas un locale tout fait
|
tout fait ou pas, mon locale à moi ((c) 1995 by P.J. Plauger, du
Platform SDK Microsoft 2005) ne contient aucun constructeur avec le
prototype (??, numpunct<?>*); je mets un "??" pour le
"std::cout.getLoc()" car je n'ai pas trouvé de std::cout non plus.
<hs> d'ailleurs je me demande si ce n'est pas un peu pour cela que je
préfère la complexité de mes fonctions de 8 lignes dignes d'une première
matinée d'initiation au C à la simplicité des include ""opaques"" de la
stl. </hs>
Sylvain. |
|
| Back to top |
|
 |
Arnaud Debaene Guest
|
Posted: Thu Jul 06, 2006 9:11 am Post subject: Re: écriture des nombres (formatage de sortie) |
|
|
"Sylvain" <noSpam (AT) mail (DOT) net> a écrit dans le message de news:
44ac3c9c$0$872$ba4acef3 (AT) news (DOT) orange.fr...
| Quote: |
mais dans les deux cas, la première chose à
faire, c'est de voir s'il n'y a pas un locale tout fait
tout fait ou pas, mon locale à moi ((c) 1995 by P.J. Plauger, du Platform
SDK Microsoft 2005) ne contient aucun constructeur avec le prototype (??,
numpunct<?>*); je mets un "??" pour le "std::cout.getLoc()" car je n'ai
pas trouvé de std::cout non plus.
|
Ah? J'ai pourtant testé mon exemple avec Visual 2005 sans problèmes ;-)
Arnaud |
|
| Back to top |
|
 |
KooK Guest
|
Posted: Thu Jul 06, 2006 7:49 pm Post subject: Re: écriture des nombres (formatage de sortie) |
|
|
Arnaud Debaene a écrit :
| Quote: | Il faut utiliser les locales, plus particulièrement le facet numpunct :
class MyNumPunct : public std::numpunct<char
{
protected:
virtual std::string do_grouping() const
{
return "\3"; //groupes de 3 chiffres. Oui, le formattage de cetet
chaine est stupide.....
}
virtual char do_thousands_sep() const
{
return ' '; //séparés par espace
}
};
int main()
{
MyNumPunct* punct=new MyNumPunct(); //will be destroyed by the locale
destructor
//create a new locale based on cout, but using our specific numpunct
std::locale loc(std::cout.getloc (), punct);
std::cout.imbue (loc);
std::cout<<2123456789<<std::endl;
}
cf
http://www.roguewave.com/support/docs/leif/sourcepro/html/stdlibref/num-put.html
pour plus de détails.
Arnaud
MVP - VC
|
Merci pour cette réponse, je ne connaissais pas le système des locales.
Je suis même surpris de voir que ma question a mené tant de réflexions.
Chez moi ta réponse marche très bien (g++, Debian), mais j'ai pu faire
encore plus simple :
int main(void)
{
double pi_M = 3141.5926;
//pour afficher correctement
cout.setf(ios::fixed);
cout << setprecision(4);
cout << pi_M << endl; //3141.5926
//pour comparer les sorties
printf("printf : %.4f\n", pi_M); //3141.5926
cout << "cout.imbue(cout.getloc())\n";
//meme resultat que locale::global(locale(""));
cout.imbue(cout.getloc());
cout << pi_M << endl; //3141.5926
printf("printf : %.4f\n", pi_M); //3141,5926 -> la virgule
cout << "cout.imbue(locale::locale(\"fr_FR.UTF-8\"))\n";
cout.imbue(locale::locale("fr_FR.UTF-8"));
cout << pi_M << endl; //3 141,5926 -> OK
printf("printf : %.4f\n", pi_M); //3141,5926 -> pas d'espace
return 0;
}
Voilà en choisissant tout simplement la bonne locale , pas sûr que
sous windows ça marche (mais je m'en moque). En C le mécanisme est
analogue d'après ce que j'ai lu.
Par contre j'imagine que si je veux grouper les décimales par trois il
va falloir que je dérive _mais je me sers de moins de 3 décimales pour
le moment.
Encore merci,
KooK |
|
| Back to top |
|
 |
Olivier Miakinen Guest
|
Posted: Thu Jul 06, 2006 8:04 pm Post subject: Re: écriture des nombres (formatage de sortie) |
|
|
Le 06/07/2006 16:49, KooK a écrit :
| Quote: | [...]
cout << "cout.imbue(locale::locale(\"fr_FR.UTF-8\"))\n";
cout.imbue(locale::locale("fr_FR.UTF-8"));
cout << pi_M << endl; //3 141,5926 -> OK
printf("printf : %.4f\n", pi_M); //3141,5926 -> pas d'espace
return 0;
}
Voilà en choisissant tout simplement la bonne locale , pas sûr que
sous windows ça marche (mais je m'en moque). En C le mécanisme est
analogue d'après ce que j'ai lu.
|
Il serait intéressant de voir ce que cela donne pour l'Inde et le
Pakistan (malheureusement je ne connais pas les codes de langue et
de pays).
<cit. http://www.miakinen.net/vrac/nombres#chiffres>
Dans quelques pays (Inde et Pakistan), les chiffres sont séparés
par paires, sauf les 3 premiers (10,00,000 = 1 000 000) [quid].
</>
| Quote: | Par contre j'imagine que si je veux grouper les décimales par trois il
va falloir que je dérive _mais je me sers de moins de 3 décimales pour
le moment.
|
Dans mes recherches pour ma page sur l'écriture des nombres, je n'ai
rien trouvé à propos d'une éventuelle séparation des décimales. Par
défaut, je supposerais donc qu'il n'y en a pas (et que le comportement
que tu as constaté est donc correct).
--
Olivier Miakinen |
|
| Back to top |
|
 |
Olivier Miakinen Guest
|
Posted: Thu Jul 06, 2006 8:31 pm Post subject: Re: écriture des nombres (formatage de sortie) |
|
|
Le 06/07/2006 17:04, Olivier Miakinen a écrit :
| Quote: |
Il serait intéressant de voir ce que cela donne pour l'Inde et le
Pakistan (malheureusement je ne connais pas les codes de langue et
de pays).
|
J'ai trouvé : dans les deux cas c'est en hindi, code "hi" (j'ignore si
le nom du pays est obligatoire).
Confirmation sur <http://joel.toonywood.org/blog/2005-08.html#e.19> :
<cit.>
Petite curiosité au sujet des chiffres, en Inde, ils ne séparent pas par
milliers comme on le fait (milliers, millions, milliards, ...), mais
regroupent d'abord les trois derniers chiffres comme nous, ensuite,
c'est cent mille (1,00,000) aussi appelé lakh, et après dix millions
(1,00,00,000) : crore [...]
</cit.>
| Quote: | Par contre j'imagine que si je veux grouper les décimales par trois il
va falloir que je dérive _mais je me sers de moins de 3 décimales pour
le moment.
Dans mes recherches pour ma page sur l'écriture des nombres, je n'ai
rien trouvé à propos d'une éventuelle séparation des décimales. Par
défaut, je supposerais donc qu'il n'y en a pas (et que le comportement
que tu as constaté est donc correct).
|
Là, la question reste ouverte.
--
Olivier Miakinen
Troll du plus sage chez les conviviaux : le nouveau venu, avec
son clan, s'infiltre dans les groupes de nouvelles. (3 c.) |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Thu Jul 06, 2006 10:09 pm Post subject: Re: écriture des nombres (formatage de sortie) |
|
|
Olivier Miakinen wrote:
| Quote: | Le 06/07/2006 16:49, KooK a écrit :
[...]
cout << "cout.imbue(locale::locale(\"fr_FR.UTF-8\"))\n";
cout.imbue(locale::locale("fr_FR.UTF-8"));
cout << pi_M << endl; //3 141,5926 -> OK
printf("printf : %.4f\n", pi_M); //3141,5926 -> pas d'espace
return 0;
}
Voilà en choisissant tout simplement la bonne locale ,
pas sûr que sous windows ça marche (mais je m'en moque). En
C le mécanisme est analogue d'après ce que j'ai lu.
Il serait intéressant de voir ce que cela donne pour l'Inde et
le Pakistan (malheureusement je ne connais pas les codes de
langue et de pays).
cit. http://www.miakinen.net/vrac/nombres#chiffres
Dans quelques pays (Inde et Pakistan), les chiffres sont séparés
par paires, sauf les 3 premiers (10,00,000 = 1 000 000) [quid].
/
|
C'est prévu. Il faut simplement que do_grouping renvoie "\3\2"
(et que do_thousands_sep renvoie ',', évidemment). La règle,
c'est que le dernier grouping se répète.
Plus intéressant, c'est le cas de l'arabe, où les chiffres
apparaissent avec le chiffre de poids faible d'abord, à
l'inverse des notres, du point de vue de la direction normale de
l'écriture.
| Quote: | Par contre j'imagine que si je veux grouper les décimales
par trois il va falloir que je dérive _mais je me sers de
moins de 3 décimales pour le moment.
Dans mes recherches pour ma page sur l'écriture des nombres,
je n'ai rien trouvé à propos d'une éventuelle séparation des
décimales. Par défaut, je supposerais donc qu'il n'y en a pas
(et que le comportement que tu as constaté est donc correct).
|
Je suppose par là qu'il veut dire : les chiffres derrière le
décimal. En effet, la norme ne prévoit rien. Dans la pratique,
je crois que c'est assez arbitraire ; ça ne m'étonnerait pas,
par exemple, de voir une table de logrithmes où les chiffres
sont régroupés par cinq. D'après mes souvenirs, Plauger a dit
une fois que son implémentation (donc, celle de VC++) a une
extension pour le supporter, mais je n'en sais pas plus (et
l'extension n'est peut-être présente que dans les versions
étendues de la bibliothèque qu'il vend directement).
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
Olivier Miakinen Guest
|
Posted: Thu Jul 06, 2006 10:33 pm Post subject: Re: écriture des nombres (formatage d e sortie) |
|
|
Le 06/07/2006 19:09, kanze a écrit :
| Quote: |
Il serait intéressant de voir ce que cela donne pour l'Inde et
le Pakistan (malheureusement je ne connais pas les codes de
langue et de pays).
cit. http://www.miakinen.net/vrac/nombres#chiffres
Dans quelques pays (Inde et Pakistan), les chiffres sont séparés
par paires, sauf les 3 premiers (10,00,000 = 1 000 000) [quid].
/
C'est prévu. Il faut simplement que do_grouping renvoie "\3\2"
(et que do_thousands_sep renvoie ',', évidemment). La règle,
c'est que le dernier grouping se répète.
|
C'est une bonne nouvelle.
| Quote: | Plus intéressant, c'est le cas de l'arabe, où les chiffres
apparaissent avec le chiffre de poids faible d'abord, à
l'inverse des notres, du point de vue de la direction normale de
l'écriture.
|
Je ne savais pas comment c'était traité en C et C++, mais dans les
pages HTML avec Unicode, c'est juste un peu plus compliqué que ça :
les chiffres apparaissent bien dans le même « ordre » que pour nous
(chiffre de poids fort en premier), mais c'est la direction d'écriture
qui change en cours de route (de right-to-left pour les lettres, elle
passe temporairement à left-to-right pour les nombres).
Si la même convention existait en français, le texte « Voilà 542 euros »
s'écrirait ainsi :
V
oV
ioV
lioV
àlioV
àlioV
5 àlioV
54 àlioV
542 àlioV
542 àlioV
e 542 àlioV
ue 542 àlioV
rue 542 àlioV
orue 542 àlioV
sorue 542 àlioV
| Quote: | Dans mes recherches pour ma page sur l'écriture des nombres,
je n'ai rien trouvé à propos d'une éventuelle séparation des
décimales. Par défaut, je supposerais donc qu'il n'y en a pas
(et que le comportement que tu as constaté est donc correct).
Je suppose par là qu'il veut dire : les chiffres derrière le
décimal.
|
Oui, exactement. En français on dirait « les chiffres après la
virgule », ou « les chiffres après le point décimal » si on parle
d'un texte anglais. Mais on les appelle aussi tout simplement les
« décimales ».
<cit. http://atilf.atilf.fr/>
DÉCIMALE
II. Substantif
A. Subst. fém.
1. MATH. Chiffre placé à droite de la virgule dans un nombre décimal.
</cit.>
| Quote: | En effet, la norme ne prévoit rien. Dans la pratique,
je crois que c'est assez arbitraire ; ça ne m'étonnerait pas,
par exemple, de voir une table de logrithmes où les chiffres
sont régroupés par cinq.
|
Oui, je reconnais que tu as raison : j'en ai déjà vu.
| Quote: | D'après mes souvenirs, Plauger a dit
une fois que son implémentation (donc, celle de VC++) a une
extension pour le supporter, mais je n'en sais pas plus (et
l'extension n'est peut-être présente que dans les versions
étendues de la bibliothèque qu'il vend directement).
|
Ok.
--
Olivier Miakinen |
|
| Back to top |
|
 |
Sylvain Guest
|
Posted: Fri Jul 07, 2006 2:23 am Post subject: Re: écriture des nombres (formatage d e sortie) |
|
|
Arnaud Debaene wrote on 06/07/2006 08:13:
| Quote: |
Ah? J'ai pourtant testé mon exemple avec Visual 2005 sans problèmes
|
j'ai indiqué "Platform SDK" (package bin/inc/lib) pas clean-install de
vs2005, ça fait surement une diff sur le contenu.
et tu l'as testé avec les include idoines, comme mon vocabulaire de base
se limite à stdio.h et string.h, ça ne pouvoit pas compiler tout seul -
c'est peut être une idée utile d'indiquer ses incl, non ?
Sylvain. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|