Je n'ai jamais utilis� std::string. Je commence donc, il n'est jamais trop tard
Mais me voici sur un premier soucis, convertir des "valeurs" en string. Bref, je cherche de quoi faire l'�quivalent des itoa, sprintf, etc, avec des string.
Merci.
Je n'ai jamais utilis� std::string. Je commence donc, il n'est jamais trop tard
Mais me voici sur un premier soucis, convertir des "valeurs" en string. Bref, je cherche de quoi faire l'�quivalent des itoa, sprintf, etc, avec des string.
Merci.
Bonjour,
La FAQ ?
Oui, merci.
A d�faut de mieux je passe parfois par l'interm�diaire des strstream, mais je trouve �a particuli�rement lourd et peu �l�gant. J'en arrive � pr�f�rer alors ce bon vieux et efficace itoa(), la conversion de 'int' ou 'unsigned' en str �tant un cas (tr�s) fr�quent. Dans d'autres cas le sprintf() est assez g�nial pour tout type de pr�sentation des nombres (precision, mantisse, base, etc).
Il n'y a pas d'�quivalent en manipulant directement les std::string ? Une classe d�riv�e avec des m�thodes suppl�mentaires ?
Non mais rien ne t'emp�che de te faire des petites fonctions template qui te convertisse n'importe quoi en string, et un string en n'importe quoi. En utilisant les stringstream.Il n'y a pas d'�quivalent en manipulant directement les std::string ?
Un exemple se trouve ici:
http://farscape.developpez.com/Articles/Conversions/
Il y a boost::lexical_cast qui emballe cette m�thode dans un appel de fonction unique.
Ma session aux Microsoft TechDays 2013 : D�velopper en natif avec C++11.
Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage � la d�couverte d'un nouveau monde
Je donne des formations au C++ en entreprise, n'h�sitez pas � me contacter.
Merci, je vais regarder un peu tout �a. Et apronfondir les strstream.
Au fait, c'est quoi c++/cli ? Jamais entendu parler...
Salut,
Honnetement, je ne vois pas vraiment ce qu'il y a de "si lourd que cela" � �crire un code proche de
quand on voit les soucis qui peuvent apparaitre avec les fonctions issues du C...
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8 const std::string convert() { float f = 3.1415926; int i = 5; std::stringstream ss; ss<<"le reel vaut :"<<f<<" et l'entier :"<<i; return ss.str(); }
En plus, l'utilisation de flux de base (istream et ostream) te permet de t'assurer une certaine continuit� dans le traitement des classes:
pourrait �tre, � ton gout, utilis� des mani�res suivantes:
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10 class MaClass { public: MaClass():f(301415926),i(5){} friend class std::ostream& operator<<(std::ostream& ofs, const MaClass& c) { ofs<<"le reel vaut :"<<f<<" et l'entier :"<<i; return ofs; } };
Comme tu l'aura remarqu�, l'�norme avantage � l'utilisation des flux de donn�es est *r�element* de fournir une syntaxe identique en tous temps
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 int main() { /* création d'une instance de la classe */ MaClass c; /* affichage sur la sortie standard */ std::cout<<c<<std::end; /* nous aurions pu choisir cerr ou clog, si nous * avions voulu un rapport d'erreur ou un log * d'activités ;-) */ /* ou l'écrire dans un fichier particulier */ std::ofstream ofs("fichier.txt"); ofs<<c<<std::endl; /* et même en arriver à convertir le tout en std::string */ std::stringstream sstr; sstr<<c; std::string s = sstr.str(); return 0; }![]()
A m�diter: La solution la plus simple est toujours la moins compliqu�e
Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
mon tout nouveau blog
OK, convaincu, merci
Ce n'est qu'une (bonne) habitude � prendre finalement.
Exactement...
En allant � peine plus loin, et bien que je connaisse le C et que je lui accorde tout le cr�dit qu'il m�rite, je dirais m�me que la bonne habitude � prendre est de toujours pr�f�rer les solutions propres au C++ lorsqu'elles existent � toute alternative issue du C...
A de tr�s rares exceptions pr�s (car il est vrai qu'il n'est pas vraiment �vident d'impl�menter un algorithme md5 avec les std::string) ce sera de nature � t'apporter facilit� et s�curit�![]()
A m�diter: La solution la plus simple est toujours la moins compliqu�e
Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
mon tout nouveau blog
Je remonte un peu ce fil car, bien que "facile" et "lisible", l'usage de string et stringstream ne semble pas tr�s performant.
Je me demandais donc si ce code peut rendre la conversion plus rapide:Mais je vous vois d�j� hurler d'ici...
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3 std::string s; s.resize(12); itoa(value,s.begin(),10);
Ou alors quelque chose comme ceci:Je sais ce n'est pas propre.
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3 std::string s; s.resize(12); itoa(value,reinterpret_cast<char *>(s.data()),10);
Mais le but est de demander � std::string d'allouer un certain espace contigu et de le proposer � l'ext�rieur pour utilisation en �criture (dans l'optique d'�viter des copies multiples).
En marge, je constate que d'une mani�re g�n�rale, l'usage des stream et de string g�n�re du code qui passe plus de temps � allouer et copier des tampon de m�moire qu'au traitement fonctionnel d�sir�.
Je retire temporairement le caract�re r�solu de ce fil pour avoir votre avis.
Si j'ai bien compris, le moyen "propre" pour acc�der au contenu d'un std::string en �criture est de passer par un iterator. Du coup je ne vois pas d'autre moyen que de r��crire l'algo de conversion, comme ceci par exemple:Ce code me semble s�r et portable car ind�pendant de l'impl�mentation de std::string.
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 std::string ul2string(unsigned long value) { char buf[12]; char *bufp=buf; for(;;) { *bufp++=(char)(value % 10u); if ((value/=10u)==0ul) break; } std::string s; s.resize(bufp-buf); std::string::iterator it_s=s.begin(); while (bufp!=buf) { char c=*--bufp; *it_s=(char)(c+'0'); ++it_s; } return s; }
Une alternative est de passer la std::string en param�tre par r�f�rence plut�t que de la renvoyer par valeur.
Ce n'est pas une bonne id�e. Ne serait-ce que parce que rien ne te garantie la taille d'un unsigned long! Sur 64 bits, ton char[12]
La bonne solution reste de passer par les stream.
Ressources propos�es par 3DArchi - Les fonctions virtuelles en C++ - Cours et tutoriels C++ - FAQ C++ - Forum C++.
J'avais pens� � ce
char buf[12];
qu'on peut judicieusement remplacer par
char buf[LONG_MAX_DIGITS];
... � condition qu'il existe une macro d�fine par le compilateur (oui mais en base 10 , 2, 16 ?).
Sinon voici
char buf[sizeof(long)*3];
![]()
Ressources propos�es par 3DArchi - Les fonctions virtuelles en C++ - Cours et tutoriels C++ - FAQ C++ - Forum C++.
A vrai dire, ce qui me fait hurler, c'est que tu oublie un principe essentiel:
La premi�re qualit� d'un code (j'irais presque jusqu'� dire: avant m�me que celle qui consiste � faire ce qu'on attend de lui) est donc... d'�tre facilement lisible par la personne qui l'a devant les yeuxun code source est plus souvent �tudi� ou lu que compil�
De plus, je ne le r�p�terai jamais assez, la solution la plus simple est toujours la moins compliqu�e... heu... pardon: la meilleure
Partant de l�, il me semble bien plus coh�rent d'avoir recours �... des solutions "simples", et tu avouera que celle qui passe par les flux de conversions est clairement celle qui donne un r�sultat coh�rent en demandant la logique la moins complexe
Enfin, il ne faut pas oublier que, tant la classe string que les classes *stringstream sont � la base des classes template (m�me si elles le cachent bien)...
Cela implique que le compilateur a toutes les latitudes possibles pour apporter des optimisations et fournir quelque chose qui sera - au final - vraisemblablement bien plus optimis� que tout ce que tu pourrais faire de ton cot�
Personnellement, il y a trois points qui me chagrinent �norm�ment:
- j'ai horreur de ne pas donner les trois param�tres n�cessaires � une boucle "pour"
- L'utilisation de l'instruction break m'horripile s'il y a moyen de faire autrement
- Quitte � ce que cela prenne quelques lignes de code de plus, je pr�f�re respecter la r�gle du "une ligne, une instruction", et �viter au maximum les effets de bord...
Ce n'est sans doute que pinaillage et "capilotraction", mais j'aurais fortement pr�f�r� quelque chose qui prenne une forme proche de
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6 while(value>0) { *bufp=(char)(value%10); value/=10; bufp++; }
A m�diter: La solution la plus simple est toujours la moins compliqu�e
Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
mon tout nouveau blog
Et voil� comment on change un code correct en un code incorrect, en pr�tendant le code initial illisible. Permet-moi ainsi de corriger ta correction
Dans le cadre du forum, j'appr�cie ton intervention pour corriger le code "illisible", car elle peut m'aider � me d�barraser de certaines (mauvaises ?) habitudes. Mais en entreprise, changer le code ancien mais �prouv� d'un vieux singe sous pr�texte de lisibilit� est passible au mieux d'une prime ou d'une augmentation manqu�e, au pire de...
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7 do { *bufp=(char)(value%10); value/=10; bufp++; } while(value>0);Surtout quand le code modifi� ne r�pond plus aux attentes.
Cependant, je n'ai pas la r�ponse � mon interrogation.
Suis-je en droit de mettre en doute le caract�re r�p�titif et non n�cessaire des multiples allocations et copies de tampons de m�moire lorsqu'on passe par l'interm�diaire des stringstream ?
Ou bien est-ce que j'�crase et je fais comme il se doit d'�tre fait sans chercher � faire mieux ? (en appliquant � la lettre le dicton qui dit que "le mieux est l'ennemi du bien").
Effectivement, j'�tais un peu fatigu� lorsque j'ai �crit le code
Je te l'accorde, mais, le fait de jouer avec les effet de bords et de faire plusieurs choses � la fois n'est de toutes mani�res jamais bonDans le cadre du forum, j'appr�cie ton intervention pour corriger le code "illisible", car elle peut m'aider � me d�barraser de certaines (mauvaises ?) habitudes. Mais en entreprise, changer le code ancien mais �prouv� d'un vieux singe sous pr�texte de lisibilit� est passible au mieux d'une prime ou d'une augmentation manqu�e, au pire de...Surtout quand le code modifi� ne r�pond plus aux attentes.
Et tu as semble-t-il trouv� rapidement le d�faut de ma logique
Sauf erreur, les buffers allou�s le sont de mani�re "compens�e".... Ce n'est pas parce que tu aurais 20 �l�ments � placer dans ton buffer que tu auras... 20 allocations et autant de lib�ration de m�moireCependant, je n'ai pas la r�ponse � mon interrogation.
Suis-je en droit de mettre en doute le caract�re r�p�titif et non n�cessaire des multiples allocations et copies de tampons de m�moire lorsqu'on passe par l'interm�diaire des stringstream ?
Ou bien est-ce que j'�crase et je fais comme il se doit d'�tre fait sans chercher � faire mieux ? (sans oublier que parfois le mieux est l'ennemi du bien).
En outre, je te rappellerais trois principes importants:
Dans, mettons, 90% des cas, une optimisation pr�matur�e est la route de toutes les enfers L'ex�cution passe g�n�ralement 80% de son temps dans 20% du code Avant de vouloir gagner quelques cycles d'horloge en cherchant la "meilleur mani�re d'�crire quelque chose", il est bien plus int�ressant de trouver la logique qui permettra d'�viter le maximum d'it�ration "non n�cessaires"
Bref, selon moi, dans un premier temps, il vaut mieux �craser et faire "comme il se doit" (bien que, dans ce cas, j'aurais tendance � plut�t dire "au plus facile")
Si, vraiment, lors du profiling, tu te rend compte que la m�thode "simple" demande �norm�ment de temps et / ou de ressources, ta premi�re r�action devrait �tre de s'interroger sur la complexit� des algorithme et de voir s'il n'est pas possible de la diminuer (passer d'une complexit� en O(n) � une complexit� en O(log(n)), par exemple ou, simplement, t'assurer de l'utilit� des chaque conversion)
Si l'objectif n'est toujours pas atteint une fois que tu as la certitude que tes algorithme ne font pas plus de conversions que n�cessaire et que le profiling t'indique clairement que ce sont les conversions qui sont encore le "goulot d'�tranglement", alors, il sera toujours temps de r�fl�chir � un moyen plus rapide d'effectuer les conversions, et de ne le garder que si le gain est r�ellement significatif (re-profiling et benchmarks � l'appui)
A m�diter: La solution la plus simple est toujours la moins compliqu�e
Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
mon tout nouveau blog
J'aurais pu (du) �diter ma r�ponse pour y rajouter ce qui suit, mais comme je te propose une autre mani�re d'envisager les choses, autant te faire une autre r�ponse
En effet, l'une des solutions envisageables pour �viter au maximum les conversions pourrait �tre de travailler avec un cache.
Tu d�clares une variable de type "chaine de caract�res" qui "suit" ta valeur num�rique, que tu vide lorsque la valeur num�rique change dont tu teste le contenu (vide ou non) avant d'effectuer la conversion.
De cette mani�re la conversion peut n'�tre effectu�e qu'une fois au lieu de (bien souvent) entre deux modifications de la valeur![]()
A m�diter: La solution la plus simple est toujours la moins compliqu�e
Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
mon tout nouveau blog
Partager