IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

Problème avec string


Sujet :

C++

  1. #1
    Membre régulier
    Inscrit en
    Juin 2009
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 10
    Par défaut Problème avec string
    Et oui c'est encore moi

    Cette fois si c'est un petit problème avec la bibliothèque 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
    int dec_bin(int dec)
    {
    	int a, i;
    	string t = "";
     
    	do
    	{
    		a = 0;
    		i = dec;
    		while(i!=1 && i!=0)
    		{
    			i -= 2;
    			a += 1;
    		}
    		t = Convert.ToString(dec-(2*a))+t;
    		dec = a;
    	}
    	while(dec!=0);
     
    	return t;
    }
    Le compilateur me refuse la ligne t = Convert.ToString(dec-(2*a))+t; qui marche dans mon bouquin ou même dans des tuto que j'ai trouvé sur internet mais pas dans mon compilateur...

    Je vous remercie d'avance.

  2. #2
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Convert est de quel type?

  3. #3
    Membre régulier
    Inscrit en
    Juin 2009
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 10
    Par défaut
    Citation Envoyé par Goten Voir le message
    Convert est de quel type?
    Se n'est pas une variable, c'est une fonction qui convertit le résultat de dec-(2*a))+res en un string dans t.

    A moins qu'il existe une autre injonction pour transformer une variable int en string

  4. #4
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Alors c'est pas du C++... Je suppose que ce que tu veux faire c'est transformé un nombre en string? Si oui alors faut faire ta propre fonction en utilisant un ostringstream, t'as des exemples dans la faq.

  5. #5
    Membre régulier
    Inscrit en
    Juin 2009
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 10
    Par défaut
    Citation Envoyé par Goten Voir le message
    Alors c'est pas du C++... Je suppose que ce que tu veux faire c'est transformé un nombre en string? Si oui alors faut faire ta propre fonction en utilisant un ostringstream, t'as des exemples dans la faq.
    Excusez moi je n'ai pas compris le sens de votre phrase. (HEIN?)

    Non se que je souhaite faire c'est convertir un décimal en binaire.
    Pour cela, j'ai besoin de la concaténation de string et donc convertir le résultat de la concaténation en question dans un [i]int[/].

  6. #6
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par kahn_onjy_bryce Voir le message
    Se n'est pas une variable, c'est une fonction qui convertit le résultat de dec-(2*a))+res en un string dans t.

    A moins qu'il existe une autre injonction pour transformer une variable int en string
    C'est du .NET, la classe Convert. C'est pour ca.

    En C, tu ferais (ca marche en C++ mais c'est du C)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *itoa(int valeur,char *s,int base)
    qui fait cela, dans la base de ton choix (il faut juste lui passer un tableau de chars de taille suffisante). Donc un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    string(itoa(valeur,chaine,base));
    devrait faire des miracles, par exemple avec base=2... Il te faut alors passer un tableau de 33 char.

    En C++, la manière correcte de faire est qqchose comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    string tostring(int i)
    {
    ostringstream oss;
    oss<<i;
    return oss.str();
    }
    Tu peux utiliser des manipulateurs pour effectuer une conversion vers d'autres bases, je crois...

    Francois

  7. #7
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    http://cpp.developpez.com/faq/cpp/?p...RINGS_numtostr

    Voilà la référence de la faq

    edit : grillé

  8. #8
    Invité
    Invité(e)
    Par défaut
    En fait, pour traduire en représentation binaire, je ne suis pas certain que la solution de la FAQ (ou une modification triviale de celle ci) fonctionne...

    En revanche, les tableaux bitset<> ont une fonction to_string(), qui fait tout le boulot.

    Il doit donc falloir quelque chose comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    string int_to_bin(int value)
    {
    bitset<numeric_limits<int>::digits + 1> bs(value);
    string s=bs.to_string();
    // elimine les bits à zéros à gauche
    string::size_type pos(s.find_first_not_of('0'));
    return (pos==string::npos?"0":s.substr(pos));
    }
    Francois

  9. #9
    Membre régulier
    Inscrit en
    Juin 2009
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 10
    Par défaut
    Ah ça fonctionne parfaitement merci beaucoup.

    Maintenant dans l'autre sens.
    Bon j'ai regardé http://cpp.developpez.com/faq/cpp/?p...RINGS_strtonum se qui donne :

    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
    22
    23
    24
    25
    26
    27
    28
    29
    int toint(string a)
    {
    	std::istringstream iss( a );
    	int b;
    	iss >> b;
    	return b;
    }
     
    int dec_bin(int dec)
    {
    	int a, i;
    	string t;
     
    	do
    	{
    		a = 0;
    		i = dec;
    		while(i!=1 && i!=0)
    		{
    			i -= 2;
    			a += 1;
    		}
    		t = tostring(dec-(2*a))+t;
    		dec = a;
    	}
    	while(dec!=0);
    	t = toint(t);
    	return t;
    }
    Le compilateur me renvoie :
    DM1.cpp:42: erreur: cannot convert ‘std::string’ to ‘int’ in return

    @fcarton : Ben je vois que c'est bien plus pratique que se que j'ai fait mais je suis déjà en train de digresser sur le sujet car le sujet dit qu'il faut utiliser des tableaux d'entier ou de caractères. J'espère que le professeur sera clément en m'autorisant l'utilisation de string.

  10. #10
    Invité
    Invité(e)
    Par défaut
    C'est tes dernières lignes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    t = toint(t);
    return t;
    Comme t est un string, ca va pas aller... fais juste

    return toint(t);

    et tout ira bien

    PS si tu dois avoir des tableaux de caractères, alors prends itoa()...

    Francois

  11. #11
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    La solution la plus simple de toutes, c'est surement celle qui consiste à utiliser la classe qui permet, précisément, de travailler sur un tableau de bit: la classe bitset, disponible dans l'espace de noms std, par inclusion du fichier d'en-tête <bitset>...

    En effet, l'ensemble des valeurs que tu peux vouloir manipuler est, naturellement, représenté sous la forme binaire en mémoire, et il est donc "logique" d'envisager d'utiliser une classe qui permet de manipuler des bits lorsque l'on veut pouvoir... les manipuler...

    De plus, cette classe dispose d'une fonction membre qui, justement, permet de récupérer ce tableau de bits sous la forme d'une chaine de caractères, pour le cas où tu voudrais pouvoir concaténer cette chaine avec une autre...

    Au final, tu pourrais te retrouver avec un code aussi simple que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <iostream> //pour l'affichage
    #include <string> //pour les chaines
    #include <bitset> // pour les bitset
    int main()
    {
        size_t i=255;
        std::bitset<sizeof(i)> tab(i);
        std::cout<< tab<<std::endl;
        std::string str("la valeur en binaire de 255 est ");
        str+=tab.to_string();
        std::cout<<str<<std::endl;
        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

  12. #12
    Invité
    Invité(e)
    Par défaut
    Salut Koala01,

    Deux petites questions/remarques :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    size_t i=255;
    std::bitset<sizeof(i)> tab(i);
    Ca va renvoyer un tableau trop court, ca, non? sizeof() renvoie une taille en octetssizeof(i) ca vaut 4 (si i est un size_t, représenté comme un unsigned int), et ca va nous créer un tableau de 4 bits... Faudrait 8*sizeof(i), non? (mais je pense que numeric_limits<size_t>::digits serait plus propre.

    Dans ce cas, le bitset<>::to_string() renverra une chaine de 32 caractères, donc dans le cas présent "00000000000000000000000011111111". Je pense qu'il faudrait tronquer les zéros du début.

    Francois

  13. #13
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Bien vu... j'étais distrait

    Il faut bien multiplier sizeof par le nombre de bits du type envisagé

    Et, effectivement, tu risque d'avoir une série de 0 inutiles, mais tu peux alors envisager l'utilisation des fonctions membres substr et find_first_of (ou find_first_not_of) de la classe string pour les tronquer...

    cela t'emmenerait à un code proche de
    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
    int main
    {
        size_t i=255;
        /* transformons cette valeur en binaire, et récupérons la dans
         * une chaine de caractères
         */
        std::bitset<std::numeric_limits<size_t>::digits>  tab(i);
        std::string result=tab.to_string();
        /* supprimons les 0 inutiles */
        result=result.substr(result.find_first_not_of("0"));
        /* cela aurait pu prendre la forme de
           result=result.substr(result.find_first_of("1"));
         */
        std::cout<<result<<std::endl;
        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

  14. #14
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    hum fait étonnant, ma version de la STL (fourni avec mingw 3.14) ne contient pas la méthode to_string(). Faut que je test sous gcc pour voir.


    (je dis ça au cas où tu _le PO_ soit sous mingw, que tu t'arraches pas les cheveux pour rien)

  15. #15
    Invité
    Invité(e)
    Par défaut
    Ouais, je mettrais encore un petit test à la fin pour le cas où le nombre vaut zéro (pour imprimer une chaine "0" et pas la chaine nulle).

    Sur numeric_limits<>::digits, je me pose une question...

    L'avantage du code qu'on a là est qu'il peut facilement être transformé en un template qui donnerait la représentation binaire de tout type scalaire, tout ce qu'on a dans numeric_limits, en fait.

    Mais peut être que sizeof(T)*8 permettrait d'avoir un code fonctionnant pour des types utilisateurs (des POD seulement, j'imagine, mais quand meme). Ca nous donnerait qqchose comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    template<typename T> string tobinary(const T &valeur) {
       bitset<8*sizeof(T)> bs(valeur);
       string s=bs.to_string();
       int pos=s.find_first_not_of("0") ;
       if(pos==string::npos) return string("0");
       return s.substr(pos);
       return s
    }
    Francois

  16. #16
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Goten Voir le message
    hum fait étonnant, ma version de la STL (fourni avec mingw 3.14) ne contient pas la méthode to_string(). Faut que je test sous gcc pour voir.


    (je dis ça au cas où tu _le PO_ soit sous mingw, que tu t'arraches pas les cheveux pour rien)
    En tout cas, elle est implémentée dans gcc 4.x.x (je te conseillerais d'ailleurs volontiers de passer à la version correspondante de MinGW, ils ont une version stable utilisant 4.3.0 )

    Sinon, au pire, les opérateurs de flux sont surchargés pour les bitsets...

    Ce sera peut être plus long, mais tu peux, au pire, envisager de passer par un stringstream pour récupérer la chaine de caractères

    Citation Envoyé par fcharton Voir le message
    Ouais, je mettrais encore un petit test à la fin pour le cas où le nombre vaut zéro (pour imprimer une chaine "0" et pas la chaine nulle).

    Sur numeric_limits<>::digits, je me pose une question...

    L'avantage du code qu'on a là est qu'il peut facilement être transformé en un template qui donnerait la représentation binaire de tout type scalaire, tout ce qu'on a dans numeric_limits, en fait.

    Mais peut être que sizeof(T)*8 permettrait d'avoir un code fonctionnant pour des types utilisateurs (des POD seulement, j'imagine, mais quand meme). Ca nous donnerait qqchose comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    template<typename T> string tobinary(const T &valeur) {
       bitset<8*sizeof(T)> bs(valeur);
       string s=bs.to_string();
       int pos=s.find_first_not_of("0") ;
       if(pos==string::npos) return string("0");
       return s.substr(pos);
       return s
    }
    Francois
    Oui, mais non...

    Je ne suis personnellement pas partisan du fait de permettre de tronquer la chaine résultant de la conversion d'un type POD...

    Pour les scalaires, cela peut encore se comprendre (quoi que, cela peut poser des problèmes au niveau des réels), mais, pour les types POD non scalaires, tu risque, si les premières valeurs sont nulles, de perdre toute information te permettant de déterminer lesquelles le sont...

    Imagine un type POD proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct POD
    {
        char c[8];
        int i[5];
    };
    qui serait converti en binaire (pas de problème là dessus), et tronqué...

    Si c[0], c[1] et c[2] sont nuls, tu va "jouir" pour arriver à t'en rendre compte
    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

  17. #17
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par fcharton Voir le message
    Mais peut être que sizeof(T)*8 permettrait d'avoir un code fonctionnant pour des types utilisateurs (des POD seulement, j'imagine, mais quand meme). Ca nous donnerait qqchose comme
    Tant qu'à faire, ne vaudrait-il pas mieux écrire sizeof(T) * CHAR_BIT

  18. #18
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par gl Voir le message
    Tant qu'à faire, ne vaudrait-il pas mieux écrire sizeof(T) * CHAR_BIT
    Ce serait encore le mieux, afin de s'éviter les problèmes relatifs à la taille même des char

    Le tout, modulo la remarque que j'ai faite plus haut, bien sur
    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

  19. #19
    Invité
    Invité(e)
    Par défaut
    @gl CHAR_BIT, bien vu!

    @ koala01 Tu as raison, si on veut un système qui marche sur les POD, il ne faut mieux pas tronquer les zéros de début de représentation. Ou peut être ne le faire que sur les types entiers, par spécialisation du template...

    Ceci dit, même avec troncature, je ne crois pas qu'on perde de l'information au point de ne pouvoir reconstituer la forme originale. Ce sont toujours les premiers zéros qui sont tronqués, et on connait la taille (via sizeof(POD)*CHAR_BITS), on peut donc facilement déduire le nombre de bits à zéro qu'on a éliminé...

    Mais ca reste une mauvaise idée de les éliminer.

    Francois

  20. #20
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par fcharton Voir le message
    Ceci dit, même avec troncature, je ne crois pas qu'on souffrirair beaucoup : ce sont toujours les premiers zéros qui sont tronqués, et on connait la taille (via sizeof()*CHAR_BITS), on peut donc savoir exactement combien de bits à zéro on doit avoir au début.
    Ce n'est pas forcément aussi simple que ça, il faut aussi inclure les problèmes d'interprétation du au padding dans la structure qui pourrait rendre la suppression des 0 initiaux quasiment invisible.

    Ceci étant, la présence même de ce padding me laisse dubitatif quant à l'intérêt de cette conversion dans la plupart des cas sur des types utilisateurs

Discussions similaires

  1. Problème avec String.replaceall et les $
    Par Tissendel dans le forum Langage
    Réponses: 5
    Dernier message: 20/09/2011, 23h41
  2. Problème avec String
    Par user2000 dans le forum Android
    Réponses: 3
    Dernier message: 22/04/2011, 10h48
  3. Réponses: 4
    Dernier message: 08/11/2010, 16h27
  4. Petit problème avec String
    Par mhamedbj dans le forum Langage
    Réponses: 5
    Dernier message: 08/04/2007, 17h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo