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 :

Conversion d'entiers et concaténation (itoa + strcat)


Sujet :

C++

  1. #1
    Membre averti
    Inscrit en
    Novembre 2004
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 31
    Par défaut Conversion d'entiers et concaténation (itoa + strcat)
    Bonjour,

    Je ne suis pas très familier des "subtilités" du C++ et j'ai un soucis avec la conversion et concaténation de chaînes de caractère. Voilà mon problème :

    J'ai deux int indépendants: 11 et 22
    je veux obtenir lun char* de la sorte : "11-22"

    Et ça, ça ne marche pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    char* data;
    char converter [8];
     
    data = itoa(11, converter, 10);
    data = strcat(data, "-");	
    data = strcat(data, itoa(22, converter, 10));	
    printf("Data : %s", data);
    Ca m'affiche : Data : 2222.
    En fait ça marcherait si j'utilisais une variable (converter) différente dans chaque itoa... Sauf que j'ai un nombre variable d'entier à convertir, ça m'arrangerait de réutiliser le même "buffer" à chaque fois.

    PS : Ma chaîne data doit alimenter la fonction "send" d'un socket. Donc je ne peux pas jouer avec des "string" C++ je crois. Ou alors il faut que je cherche comment convertir un char* en string.

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Premier conseil, passe par std::string (#include <string>) et std::stringstream (#include <sstream>):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
       std::stringstream l_flux_str;
       std::string l_str;
       int i_1(11);
       int i_2(12);
       l_flux_str<<i_1<<"-"<<i_2;
       l_str = l_flux_str.str();
    Ensuite, si tu veux tout de même un buffer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    const char *p_str = l_str.c_str();
    Tu peux retrouver des infos sur la FAQ ou sur les tutoriels.

  3. #3
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Salut (ou plutot rebonjour xD)
    Pour rester dans un code style C (et oui, c'est du C que tu présente, pas du C++, en C++ on utilise des string comme le dis 3DArchi) :

    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
     
    #define BUF_SIZE  32 // Un petit define, c'est pratique pour les tailles de buffer
     
    // On alloue le buffer, car si tu le fait pas c'est pas itoa qui va le faire
    char* data = (char*)malloc(sizeof(char) * BUF_SIZE);
     
    // On met 0 partout dans la buffer pour être certain que la chaine résultante sera terminée par un 0
    SecureZeroMemory(data, BUF_SIZE); // Manquera ptre un cast ici
     
    // On convertie le premier nombre
    itoa(11, data, 10);
     
    // On ajoute le "-"
    strcat(data, "-"); // Pas besoin du data = strcat, puisque data sera directement modifié
     
    // On calcul la taille de la chaine
    int i = strlen(data);
     
    // On convertie le seconde nombre
    itoa(22, data + i, 10); // les pointeurs c'est super drole, avec ce +i le résultat de la conversion est directement concacténé
    Quand tu aura fini de faire mumuse avec ton data, n'oublie pas de le libérer : free(data);

    EDIT : Pour le SecureZeroMemory, j'ai utilisé celui la partant du princique que tu es sous Windows avec Visual Studio 2005+, si c'est pas le cas elle sera pas forcément disponible, mais rassures-toi, tu peux toujours utiliser la fonction memset à la place : memset(data, 0, BUF_SIZE);

  4. #4
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Ah oui, autre chose, si c'est pour faire juste un printf derriere, tu peux faire directement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    printf("Data : %i-%i", 10, 22);
    La version C++ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cout << "Data : " << 10 << "-" << 22 << endl;
    ET si tu veux, tu as aussi la possibilité de faire un printf dans un buffer plutot que sur l'écran, regardes du coté de sprintf

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Syrus Voir le message
    PS : Ma chaîne data doit alimenter la fonction "send" d'un socket. Donc je ne peux pas jouer avec des "string" C++ je crois. Ou alors il faut que je cherche comment convertir un char* en string.
    J'avais pas vu la première fois. Mais, rien n'empêche d'utiliser un std::string. Pour aller de char* vers std::string, tu as les constructeurs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    string ( const char * s, size_t n );
    string ( const char * s );
    Attention tout de même au '\0' terminal.
    Pour ton émission, donc du std::string au char, tu as string::c_str:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    sendto(ma_socket,ma_str.c_str(),ma_str.length()...);
    Idem, attention au '\0' terminal.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Par défaut
    une dernière possibilité sans passer par les stringstream:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    std::string l_str;
    int i_1(11);
    int i_2(12);
    l_str = boost::lexical_cast<std::string>(i_1) + "-" + boost::lexical_cast<std::string>(i_2);

  7. #7
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Ca implique d'utiliser Boost, même si c'est une librairie puissante et répandue c'est très loin d'être standard.
    Pour un code aussi simple c'est vraiment inutile de s'encombrer d'une librairie aussi grosse.

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Par défaut
    C'était plus pour la culture générale. Je suis d'accord avec toi que pour convertir des entiers en string dans cette méthode, l'intérêt d'utiliser boost est limité...

    PS : Il utilise des sockets, ça peut être intéressant d'aller faire un tours du côté de boost (asio).

  9. #9
    Membre averti
    Inscrit en
    Novembre 2004
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 31
    Par défaut
    Merci beaucoup pour votre aide.

    J'ai implémenté une solution à base de flux et de string (et conversion en char* pour mon socket).

  10. #10
    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
    Le code c'est du C.

    Un code déjà plus correct serait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char buffer[18];
     
    itoa(11, buffer, 10);
    strcat(buffer, "-");	
    itoa(22, buffer+strlen(buffer), 10);	
    printf("Data : %s", buffer);
    Par ailleurs itoa n'est pas une fonction standard.

  11. #11
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    C'est exactement mon code à ceci près que tu fait une allocation statique.
    Et itoa est une fonction POSIX, c'est standard sur tous les systèmes POSIX, à savoir Windows et Unix (oui Unix, pas seulement linux, sachant que MacOs est une base Unix également compatible POSIX), ca laisse pas beaucoup de système qui ne sont pas compatibles. J'ai pas mal travaillé pour de l'embarqué (sans OS) également et je n'ai jamais rencontré de système dont le compilateur n'offre pas en standard cette fonction.
    Cependant elle est déprécié dans Windows qui préfère la norme ISO C++, la fonction équivalente c'est _itoa. Il y a même une version 64bit pour les "gros" int : _i64toa.


  12. #12
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ne te contente pas de l'erreur Visual pour dire que c'est POSIX: Beaucoup de fonction sont dites "POSIX" par Visual simplement parce qu'elles ne sont pas standard C90, mais pas mal d'entre elles ne sont pas POSIX non plus:
    http://msdn.microsoft.com/en-us/libr...mmunityContent
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  13. #13
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par ctxnop Voir le message
    This POSIX function is deprecated beginning in Visual C++ 2005. Use the ISO C++ conformant _itoa or security-enhanced _itoa_s instead.
    Pas mal comme message induisant en erreur. itoa n'est pas POSIX. _itoa et _itoa_s sont "conformes a ISO C++" uniquement parce que ce sont des noms reserves a l'implementation; ce ne sont pas des fonctions definies par la norme.

  14. #14
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Oui, ces messages d'erreur sont infâmes.
    En plus, ils ont regroupé dans le même sac trois types de fonctions:
    • Fonctions vraiment compatibles POSIX: strdup().
    • Fonctions qui ont le même nom qu'une fonction POSIX, mais pas entièrement compatibles: open().
    • Fonctions ni standard, ni POSIX.


    En clair, non seulement ils généralisent mais le message d'erreur est confus. Vu que le define pour supprimer ces warnings est _CRT_NONSTDC_NO_DEPRECATE, ils pourraient simplement dire "cette fonction n'est pas standard, donc son nom sans underscore a été déprécié"...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  15. #15
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Effectivement, après de plus amples recherches je me suis laissé abusé par les MSDN, méa culpa

  16. #16
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Salut

    Moi j'ai fait du c pendant des années et je ne comprends rien a vos bricolages


    Voila ce qu'il faut faire en C
    Ou alors j'ai rien compris a la question.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char buffer[18];
    sprintf(buffer,"Data : %02d-%02d",11,22);

  17. #17
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Effectivement, c'est une solution en C. Mais comme on est dans le forum C++, on a proposé des réponses C++: avec les chaines std::string et les flux std::stringstream.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [débutant mais pas trop] conversion string->entier
    Par Biosox dans le forum Débuter
    Réponses: 5
    Dernier message: 06/01/2006, 22h41
  2. [SQL Access] Conversion d'entier en chaîne
    Par Neilos dans le forum Access
    Réponses: 2
    Dernier message: 17/06/2005, 10h58
  3. Conversion ascii - entier
    Par Jbx 2.0b dans le forum Général Python
    Réponses: 3
    Dernier message: 15/03/2005, 19h23
  4. [String] Conversion vers entier
    Par Javatator dans le forum API standards et tierces
    Réponses: 10
    Dernier message: 19/08/2004, 15h59
  5. Réponses: 6
    Dernier message: 16/05/2004, 19h03

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