Bonjour, j'ai 2 nombres ayant comme type std::string. Y a t-il un moyen de les additionner, par exemple en surchargeant l'operateur + ?
merci.
Bonjour, j'ai 2 nombres ayant comme type std::string. Y a t-il un moyen de les additionner, par exemple en surchargeant l'operateur + ?
merci.
Salut,
Etrange comme formulation mais soit !j'ai 2 nombres ayant comme type std::string
Il est tout a fait possible de le faire. Je te laisse aller sur google et taper un truc du genre "C++ surcharge des operateurs" tu verras de suite comment ca fonctionne et quelles possibiltes cela t'offre.
Bon courage
J'ai dejà essayer de surcharger l'operateur + mais sans succes. J'ai regardé un peu sur le net, et pareil.
un indice?
Voilà ce que j'avais tenté...
Et ça serait encore mieux si ça pouvait me retourner le resultat sous forme de std::string.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 int operator & +(std::string nb1, std::string nb2) { int res; res=nb1+nb2; return res; }
merci
???Voilà ce que j'avais tenté...
Code :
int operator & +(std::string nb1, std::string nb2)
{
int res;
res=nb1+nb2;
return res;
}
Outre les fautes de logique et de syntaxe, pourquoi surcharger cet operateur si c pour mettre a l'interieur :
avec nb1 et nb2 string !!!
Code : Sélectionner tout - Visualiser dans une fenêtre à part res=nb1+nb2;
Sinon dans la doc de la classe string du C++ (tout premier endroit ou il est tres utils de chercher en cas de pb) :
http://www.cppreference.com/cppstrin...operators.html
Tous les operateurs utiles dont + sont deja definis![]()
Ben je sais pas, moi ça me semblais logique ce que j'avais fait
Mais, j'ai pas compris comment faire avec ce qui est dans la doc.
Il y a bien ça:
Mais je suppose que si je passe en parametre: 2 et 6 ça va me retourner 26, et non 8...
Code : Sélectionner tout - Visualiser dans une fenêtre à part string operator+(const string& s1, const string& s2 );
Oula ...
2 : int
6 : int
"2" : string, char*, ... ca depend
si tu fais "2"+"6" ca doit probablement marcher
A revoir les bases des types de donnees C++![]()
hello,
je vois pas trop ce que tu veux faire mais peut être que ça peut t'aider:
http://www.cplusplus.com/reference/c...dlib/atoi.html
atoi Convert string to integer (function)
atol Convert string to long integer (function)
atof Convert string to double (function)
strtol Convert string to long integer (function)
Salut à tous !
Personnellement, je me pose la question de la pertinence de représenter des chiffres sous forme de chaînes de caractères. À mon avis, il faut revoir la conception.
Sinon, au niveau des chaînes de caractères, l'opérateur d'addition est surchargé et effectue une concaténation. Ainsi, le programme suivant :
Retourne sur la sortie standard la chaine « abcdef. »
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 #include <string> #include <iostream> int main (int argc, char **argv) { const std::string chaine1 = "abc"; const std::string chaine2 = "def"; std::cout << chaine1 + chaine2 << std::endl; return 0; } // main
Pour convertir une chaîne de caractères en entier, il existe deux méthodes en C++. La première vient du C, elle consiste à utiliser la fonction atoi de la bibliothèque standard C :
Le code précédent retourne « 14 » sur la sortie standard.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 #include <string> #include <iostream> #include <cstd> int main (int argc, char **argv) { const std::string chaine = "12"; const int entier = std::atoi(chaine) + 2; std::cout << entier << std::endl; } // main
La deuxième méthode consiste à utiliser un flux sur une chaîne de caractères :
Ce code également affiche « 14 » sur la sortie standard.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 #include <string> #include <iostream> #include <sstream> int main (int argc, char **argv) { std::string chaine = "12"; std::istringstream ist (chaine); int entier; ist >> entier; std::cout << entier + 2 << std::endl; } // main
Pour surcharger l'opérateur d'addition, tu peux faire ça :
Mais je te déconseille cette approche. À mon avis il faut revoir la façon dont tu stockes tes données.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 #include <string> #include <cstd> // ... int operator + (const std::string &chaine1, const std::string &chaine2) { return std::atoi(chaine1) + std::atoi(chaine2); } // int operator + (const std::string &, const std::string &)
À bientôt.
Le Farfadet Spatial
...Où les fonction convertir_en_int et convertir_en_string restent à déterminer...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 std::string operator+(std::string nb1, std::string nb2) { int res = convertir_en_int(nb1) + convertir_en_int(nb2); return convertir_en_string(res); }
Cela dit, c'est curieux de redéfinir cet opérateur pour les std::string alors qu'il existe deja.
Du coup tu ne pourras plus faire quelque chose du genre :
Edit : grillé
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 std::string a = "chaine alpha1"; std::string b = "chaine alpha2"; a + b;
Salut à tous !
Je suis bien d'accord.
Ceci, en revanche, n'est pas tout à fait exacte. Si jamais l'opérateur d'addition est surchargé de la façon que j'ai proposée, alors ceci :Du coup tu ne pourras plus faire quelque chose du genre :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 std::string a = "chaine alpha1"; std::string b = "chaine alpha2"; a + b;
Affichera sur la sortie standard : « 122 = 14. »
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 const std::string chaine1 = "12"; const std::string chaine2 = "2"; const std::string chaine3 = chaine1 + chaine2; const int entier = chaine1 + chaine2; std::cout << chaine3 << " = " << entier << std::endl;
Par contre, le compilateur indiquera une ambiguïté au moment de la compilation pour le code suivant :
À bientôt.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 const std::string chaine1 = "12"; const std::string chaine2 = "2"; std::cout << chaine1 + chaine2 << std::endl;
Le Farfadet Spatial
Sans doute qu'il récupère les valeurs d'un flux externe. Un fichier par exemple.
La meilleure solution consiste à procéder en 2 étapes:
1/ on transforme la chaine de caractères en int (et s'il vous plait, arêtez avec atoi et autres joyeusetés du C, nous sommes sur un forum c++). La solution est, une fois de plus, dans la faq: ici
2/ additionner les deux entiers.
Mais koala va vous expliquer tout ça en détail
edit: quant à la surcharge de d'addition de string, elle est à proscrire définitivement pour plusieurs raisons, et notamment pour la simple et bonne raison que l'on ne pourra plus concaténer des strings avec l'operateur +.
edit2:
As-tu testé? Non. Si l'operateur + est surchargé comme tu le dis, string3 = string1 + string2 ne compilera pas.Envoyé par farfadet spatial
Salut,
Il faut commencer par convertir chaque chaine en entier.
La classe stringstream est là pour t'y aider
Je ne crois vraiment pas que la surcharge de l'opérateur + soit réellement conseillée...
L'idéal serait plutôt, selon moi, de créer une classe personnelle qui se chargera de la transformation "transparente" de la chaine de caractères en entier, et utilisera directement la valeur convertie, avec éventuellement les opérateurs + et -
Horreur et calamité...
les fonctions ato* sont à éviter autant que possible, comme c'est le cas de toutes les fonctions issues directement du C.
Le C++ est un langage qui fournit énormément de possibilités plus sécurisantes à l'emploi que la grosse majorité des fonctions héritées du C, et il est donc fortement recommandé de leur préférer à chaque fois les possibilités C++.
Dans le cas qui nous intéresse, les *stringstream sont pleinement qualifiés pour effectuer le travail.
Ainsi, un simple code du genre de
fera parfaitement l'affaire
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 int additionne(const std::string& i1, const std::string& i2) { /* déclare un flux de conversion */ std::stringstream ss; /* introduit les valeurs sous forme de chaines dans le flux de conversion */ ss<<s1<<" "<<s2; int op1; int op2; if(!(ss>>op1>>op2)) { /* ce qu'il faut faire si l'une des chaines n'est pas compatible avec * les nombres entiers */ } /* renvoie l'addition des deux opérandes récupérés. */ return op1+op2; }(requière un #include <sstream> avant la déclaration de "ss"
)
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
Merci pour toutes vos réponses. Je vais essayer tout ça. Et pour répondre à certains qui se demandent pourquoi je dois faire ça, c'est que j'ai des variables qui prennent leur valeurs dans le contenu d'un fichier texte.
ex:
Le fichier texte:
Et dans mon code j'ai une variable std::string saQuantité a laquelle j'affecte la quantité (en string) lu dans le fichier texte.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 Nom: toto Année: 2001 Quantité: 6
Mais par la suite je peux avoir besoin d'additionner deux quantités. Voilà pourquoi.
Merci encore.
Bonjour,
Personnellement je ne suis pas tout à fait d'accord avec le fait de ne pas utiliser atoi.
Le comportement de la fonction atoi est décrit ici, et l'on peut voir qu'il se comporte aussi surement qu'un stringstream.
Et utiliser la fonction atoi est beaucoup plus léger que de créer une classe, d'allouer la chaine de caractères de la classe dynamiquement, de copier tous les caractères dans la stringstream, et d'utiliser un flux pour convertir en int.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 int additionne(const std::string& i1, const std::string& i2) { return atoi(i1.c_str())+atoi(i2.c_str()); }Pour moi la première fonction est préférable à tous points de vue. Les classes de la STL sont très utiles, mais je ne vois aucune raison valable de ne pas utiliser certaines fonctions du C pur, quand c'est plus pratique, plus court, et plus performant.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 int additionne(const std::string& i1, const std::string& i2) { std::stringstream ss; ss<<s1<<" "<<s2; int op1 = 0; int op2 = 0; return op1+op2; }
Salut à tous !
Oui, c'est bien pour ça que je pense et visiblement je ne suis pas le seul, qu'il ne vaut mieux pas enregistrer l'entier dans une chaîne, mais utiliser un flux. Peut-être n'ai-je pas été assez clair.
Au temps pour moi : je viens de le tester avec gcc et ça ne fonctionne pas, en effet.Envoyé par r0d
etEnvoyé par r0d
Ah ! Ben flûte, alors... Il va falloir que j'arrête d'utiliser les fonctions de cmath, sous prétexte que c'est du C... Ça tombe mal, j'en ai besoin tous les jours.Envoyé par koala01
Je suis bien d'accord d'une part que trop souvent on trouve un mélange de C et C++ imbuvable, généralement peu efficace et de toute façon difficile à lire et à maintenir. Et ceci est on ne peut plus vrai :
Et oui, nous sommes bien d'accord, lorsqu'on lit les données dans un fichier, les flux sont une bien meilleure solution, car plus sécurisés et permettant beaucoup plus de traitements de manière simple et élégante et que les fonctions de la bibliothèque standard C.Envoyé par koala01
Cela dit, la bibliothèque standard C a été encapsulée pour être utilisée proprement en C++ et parfois c'est une solution propre, efficace et élégante. Par exemple, lorsque dans ma ligne de commande, j'attends en deuxième argument un entier, il n'y a aucun problème pour écrire :
Plutôt que de faire un flux sur une chaîne, qui demande tout de même un peu plus de travail, tout ça pour un unique entier...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 int val = atoi(argv[2]);
À bientôt.
Le Farfadet Spatial
Ce qu'il y a, c'est que la grosse majorité des cas où tu va avoir besoin de convertir un entier en une chaine et vice-versa (voire un objet en chaine), c'est dans un contexte de flux...
Ce sera parce que tu voudra lire ou écrire dans un fichier, ou parce que tu voudra envoyer ou recevoir les données au travers d'un système quelconque de transmission, basé sur la transmission de caractères.
Dés lors, il semble tout de suite logique de passer par des flux, et le flux de conversion stringstream (i ou o selon le cas) est un prétendant des plus logique![]()
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
Salut à tous !
Dans la majorité des cas, oui, mais pas toujours... Sachons avoir un peu de souplesse (je dis ça pour moi aussi) ! D'autant que, comme le fait remarquer Coyotte504, les fonctions ato* ne sont pas moins sécurisées que des flux, juste beaucoup moins versatiles.
Cela dit, maintenant, nous savons que Nyko17 est en train de lire un fichier, donc, en effet, nous pouvons lui donner ce judicieux conseil : utilise des flux, sacrebleu !
À bientôt.
Le Farfadet Spatial
J'ai encore un petit problème:
Voici l'en-tête de mon fichier:
Voici la fonction concernée:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 #include <sstream> #include <iostream> #include <list> #include <fstream>
Et les erreurs:
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 std::string ListeVins::convertiEnIntetAjoute(std::string & Qt1, std::string & Qt2) { std::istringstream iss( Qt1 ); //ici int laQt1; iss >> laQt1; std::istringstream iss( Qt2 ); // et là int laQt2; iss >> laQt2; int res= laQt1 + laQt2; std::ostringstream oss; oss << res; std::string result = oss.str(); return result; }
ici: erreur: 'std::istringstream iss' previously declared here
là: erreur: redeclaration of 'std::istringstream iss'
Partager