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 :

Probleme avec itoa()


Sujet :

C++

  1. #1
    Membre éclairé Avatar de vdumont
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 510
    Par défaut Probleme avec itoa()
    Bonjour, jai un probleme avec itoa(), quand jessaye dutiliser la fonction il me dit quelle nest pas declaree.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #include <stdlib.h>
    ...
     
    char mess[15],mess2[10];
    strcpy(mess,"Champs_");
    itoa(i,mess2,10);
    Jai essayer std::itoa mais il dit quil nest pas membre de std.

    Je suis sous g++
    Merci!

  2. #2
    Membre émérite

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 634
    Par défaut
    itoa ce n'est pas du C++. Utilise std::string et ostringstream. Voir la FAQ pour des exemples : http://c.developpez.com/faq/cpp/?page=strings

  3. #3
    Membre éclairé Avatar de vdumont
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 510
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    for (int i=0;i<nb;i++)
            {
            char mess[15],mess2[10];
            strcpy(mess,"Champs_");
            	std::ostringstream oss;
            	oss << i;
            	mess2 = oss.str();
            //itoa(i,mess2,10);
            strcat(mess,mess2);
            legende[i]=mess ;
            }

    EDIT: Ca compile pas du tout

  4. #4
    Membre émérite

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 634
    Par défaut
    Non, str() renvoie un std::string. Ensuite si tu as vraiment besoin de const char* il y a une fonction membre de std::string qui renvoie un const char* : c_str().

    Si j'ai bien compris ce que tu voulais faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    for (int i=0;i<nb;i++)
    {
        std::ostringstream oss;
        oss << "Champs_" << i;
     
        const char* mess  = oss.str().c_str();
     
        // Tu peux maintenant utiliser mess
    }

  5. #5
    Membre éclairé Avatar de vdumont
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 510
    Par défaut
    Hum en fait mess2 est un char[10] et non un char* donc je ne peux pas affecter oss.str().c_str() a mon mess2

    affecter un string a un char[10] ca se fait parcontre?

  6. #6
    Membre émérite

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 634
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    strcpy(mess2, oss.str().c_str());
    Mais es-tu sûr d'avoir directement besoin de ce char[10] ? Tu peux rester dans le type std::string non ? Ca dépend de ce que tu fais après avec ça.

  7. #7
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int nb = 15; // ou n'importe quoi d'autre
    std::vector<std::string> legende(nb);
    for(int i=0; i<nb; ++i)
    {
    	legende[i] = "Champs_" + boost::lexical_cast<std::string>(i);
    }

  8. #8
    Membre éclairé Avatar de vdumont
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 510
    Par défaut
    En ce moment jai dans mon for:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    for (int i=0;i<nb;i++)
    {
       std::string mess;
       strcpy(mess,"Champs_");
       std::ostringstream oss;
       oss << i;
       strcat(mess,oss.str().c_str());
       legende[i]=mess ;
    }
    Ca plante un max.

    mg_solution.cpp:51: error: no matching function for call to `strcpy(std::string&, const char[8])'
    /usr/include/string.h:74: note: candidates are: char* strcpy(char*, const char*)

    mg_solution.cpp:56: error: no matching function for call to `strcat(std::string&, const char*)'
    /usr/include/string.h:70: note: candidates are: char* strcat(char*, const char*)


  9. #9
    Rédacteur
    Avatar de bigboomshakala
    Homme Profil pro
    Consultant Web .NET
    Inscrit en
    Avril 2004
    Messages
    2 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant Web .NET
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2004
    Messages : 2 077
    Par défaut
    c'est normal. comme le dit le message d'erreur strcpy prend en paramètre un char* et un const char*

  10. #10
    Rédacteur
    Avatar de bigboomshakala
    Homme Profil pro
    Consultant Web .NET
    Inscrit en
    Avril 2004
    Messages
    2 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant Web .NET
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2004
    Messages : 2 077
    Par défaut
    Citation Envoyé par loufoque
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int nb = 15; // ou n'importe quoi d'autre
    std::vector<std::string> legende(nb);
    for(int i=0; i<nb; ++i)
    {
    	legende[i] = "Champs_" + boost::lexical_cast<std::string>(i);
    }
    encore faut-il avoir boost...

  11. #11
    Membre éclairé Avatar de vdumont
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 510
    Par défaut
    Voila le hic et puisque ce nest pas mon logiciel jaimerais eviter les librairies externes.

  12. #12
    Membre éclairé Avatar de vdumont
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 510
    Par défaut
    Est-ce que cela fait du sens??

    Pour donner le code complet:


    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
     
    for (int i=0;i<nb;i++)
            {
            #ifdef GCC
               char *mess = "Champs_"; 
            	std::ostringstream oss;
            	oss << i;
               strcat(mess,oss.str().c_str());
            #else // Borland (reconnait itoa)
            	char mess[15],mess2[10];
            	strcpy(mess,"Champs_");
            	itoa(i,mess2,10);
            	strcat(mess,mess2);
            #endif
            legende[i]=mess ;
            }

  13. #13
    Membre éclairé Avatar de vdumont
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 510
    Par défaut
    Hum jai trouver mieux

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    for (int i=0;i<nb;i++)
            {
    	      char mess[15];
            sprintf(mess,"Champs_%d",i);
            legende[i]=mess ;
            }

  14. #14
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    vdumont, évite de faire du code trop pourri.
    1) Déjà tu utilises des tableaux et des chaînes C, truc à ne surtout pas faire en C++.
    Et en plus, bien qu'on t'ait parlé de std::string et compagnie, tu continues à utiliser des trucs de C (le plus drôle étant le strcat sur une std::string - tiens ça fait une erreur, comment ça se fait ?)
    2) Les macros ça fait aussi partie des trucs à éviter si possible. Tu veux mettre le comportement normal pour GCC et un comportement non standard pour tous les autres compilateurs. Ça devrait être l'inverse, mais bon, de toutes façons tu n'as pas besoin de distinguer deux cas : il suffit de bien le faire une fois pour toutes.
    3) Prenons ton code pour gcc. Déjà char *mess = "Champs_" et après tu veux faire un strcat dessus. Ça doit sûrement faire une magnifique erreur de segmentation ou un buffer overflow.
    4) Regardons maintenant pour les autres compilateurs (enfin pour Borland). Tu utilises deux variables, dont une, mess2, est parfaitement inutile, si ce n'est pour ajouter des traitements supplémentaires.
    Ton code aurait pu s'écrire plus simplement comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char mess[15] = "Champs_";
    itoa(i, mess+7, 10);
    Ce qui provoquera de gros problèmes dès que i dépassera 10 millions. Mais bon, ça n'arrivera probablement pas, étant donné que 10 millions de champs, c'est un peu lourd à manipuler.

    Si tu ne souhaites pas utiliser boost (qui est pourtant une bibliothèque très utilisée dans le C++ moderne) il faut alors utiliser directement les flux, et dans ton cas std::ostringstream correspond bien, surtout si tu utilises des std::string à la place des char* comme tu devrais.

    Edit : je viens de voir ton nouveau post, tu as tout simplement abandonné le C++ et utilisé la manière C89/90 de résoudre ce problème (en C99 on aurait peut-être préféré snprintf).
    Si tu souhaites progammer ainsi, il serait peut-être plus avisé de poser tes questions sur le forum C à l'avenir.

  15. #15
    Membre éclairé Avatar de vdumont
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 510
    Par défaut
    Loufque:

    1- Peux tu preciser quels sont les chaines C? Jai de la misere a differencier
    2- Je sais mais jattendais de retourner sous Windows pour tester davantage
    3- Peux tu expliquer pourquoi ca ferait une erreur overflow??
    4- Je sais quelle est inutile et je lavais supprimer. Je ne suis pas lauteur du code original je fais seulement modifier

    Dans ton extrait de code, tu utilise itoa, hors itoa nexiste pas en C++ donc que faire??

    Je ne peux pas utiliser boost car ce nest pas moi qui decide.

    Jignorais que sprintf etait du C.

  16. #16
    Membre éclairé Avatar de vdumont
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 510
    Par défaut
    Pour rester en C++ il aurait donc fallu la solution de Fiquet:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        std::ostringstream oss; 
        oss << "Champs_" << i; 
     
        const char* mess  = oss.str().c_str();

  17. #17
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char* mess  = oss.str().c_str();
    Alors est-ce que tu es conscient que là tu as un pointeur vers une variable qui va cesser d'exister dès qu'on passera à l'itération suivante de la boucle ?
    (C'était d'ailleurs aussi le cas dans tous les codes précédents que tu as fournis a priori, t'arrives à faire marcher ça ?)

    1) Des séquences de char terminées par un caractère nul.
    Le type séquence n'existant pas en C (les tableaux ont une taille fixe et on ne peut pas les passer par valeur) on utilise donc un pointeur vers le premier char de cette séquence pour les manipuler, le caractère nul à la fin permettant de savoir quand est-ce que cette séquence se termine.

    Les chaînes C++ (std::string) sont quant à elles des objets qui sont des séquences qui se redimensionnent automatiquement si besoin est, qui surchargent divers opérateurs pour facilitier la concaténation, l'affectation, la copie, la conversion etc. Il y a aussi des fonctions membres pour faire des opérations usuelles, et ces chaînes peuvent contenir des caractères nuls au milieu sans problème.

    3) mess est dans ce cas un pointeur vers le premier caractère d'une chaîne littérale, qui est sûrement dans ton cas un char[8];
    Avec ton strcat tu vas donc essayer d'écrire au delà de la mémoire disponible.

    Dans ton extrait de code, tu utilise itoa, hors itoa nexiste pas en C++ donc que faire??
    Il s'agissait juste d'une simplification de ton code.
    itoa est une fonction C non standard fournie par Borland.

    Une meilleure solution serait que legende soit un std::vector<std::string>.
    Bref comme j'ai donné en premier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int nb = 15; // par exemple
    std::vector<std::string> legende(nb);
    for(int i=0; i<nb; ++i)
    {
        std::ostringstream oss;
        oss << "Champs_" << i;
        legende[i] = oss.str();
    }

  18. #18
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 292
    Par défaut
    Citation Envoyé par bigboomshakala
    encore faut-il avoir boost...
    De toutes les libs boost, c'est une des plus simples à subsituer -- en particulier sur les projets qui ne peuvent plus dépendre de "nouvelles" bibliothèques externes.

    Sinon, itoa ne fait ni parti du C++, ni du C. C'est une extension propriétaire pour je ne sais plus quel compilo pouvant se lier à du C.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  19. #19
    Membre éclairé Avatar de vdumont
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 510
    Par défaut
    Hum en faisant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        for (int i=0;i<575000;i++)
            {
            std::ostringstream oss;
            oss << "Champs_" << i;
     
             const char* mess  = oss.str().c_str();
     
             legende[i] = mess;
             std::cout << legende[i];
            }
    Ca s'execute #1 sans aucun leak de mémoire... je comprend pas trop le truc du pointeur que tu dis..

    A la fin on utilise mess, ensuite on change l'itération, on redéclare tout et on ré-utilise et ainsi de suite. Je n'utilise jamais mess alors qu'il point nul part?? Je suis pas sur de comprendre, merci de m'éclairer.

  20. #20
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    La seule utilisation possible la fonction membre c_str(), c'est pour une copie immédiate. Tu ne peux pas stocker ce pointeur comme tu le fais, puisque dès la fin de l'appel à c_str(), la chaîne retournée pourra potentiellement ne plus exister.

    Il faut donc quelque chose de ce style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    for (int i=0;i<575000;i++)
            {
            std::ostringstream oss;
            oss << "Champs_" << i;
     
             strcpy(legende[i], oss.str().c_str());
     
             std::cout << legende[i];
            }
    Mais c'est vrai que c'est un peu idiot de repasser par un tableau de char alors que tu as un std::string...

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Probleme avec la copie des surfaces
    Par Black_Daimond dans le forum DirectX
    Réponses: 3
    Dernier message: 09/01/2003, 10h33
  2. Problèmes avec le filtrage des ip
    Par berry dans le forum Réseau
    Réponses: 9
    Dernier message: 30/12/2002, 07h51
  3. probleme avec la touche F10
    Par b.grellee dans le forum Langage
    Réponses: 2
    Dernier message: 15/09/2002, 22h04
  4. Probleme avec fseek
    Par Bjorn dans le forum C
    Réponses: 5
    Dernier message: 04/08/2002, 07h17
  5. [Kylix] probleme avec un imagelist
    Par NicoLinux dans le forum EDI
    Réponses: 4
    Dernier message: 08/06/2002, 23h06

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