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

Langage C++ Discussion :

Taille template de chaîne de caractères


Sujet :

Langage C++

  1. #1
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut Taille template de chaîne de caractères
    Hello,
    J'ai un problème "assez" simple que je n'arrive pas à résoudre. J'essaie de sérialiser en XML (avec TinyXML) des chaînes de caractères dont la taille est arbitraire. J'ai donc le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
      template<unsigned long Size>
      void get_value(const TiXmlElement* node, char text[Size])
      {
        std::string temp = node->GetText();
        strncpy(temp.c_str(), text, Size);
      }
     
      template<unsigned long Size>
      void set_value(TiXmlElement* node, const char text[Size])
      {
        TiXmlText* text_node = new TiXmlText(text);
        text_node->SetCDATA(true);
        node->LinkEndChild(text_node);
      }
    La deuxième fonction passe, mais pas la première. En fait, le compilateur (icc 10.1) n'arrive pas à trouver get_value, par exemple avec le code suivant (issu de mes tests unitaires) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      char new_text[16];
      SOAPRPC::get_value(pNode, new_text);
    vous avez une idée de mon erreur toute bête ?

  2. #2
    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,

    As tu, tout bêtement, essayé en précisant la taille

    Quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      char new_text[16];
      SOAPRPC::get_value<16>(pNode, new_text);
    (ou un typedef associé, why not)
    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

  3. #3
    Membre expérimenté Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Par défaut
    Bonsoir,
    Ça ne marche pas chez moi non plus. (Les deux functions en fait). Avec minGW 4.3

    La seul alternative que j'aurais serais quelque chose comme ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      template<class T>
      void get_value(const TiXmlElement* node, T text)
      {
        std::string temp = node->GetText();
        std::strncpy(&temp[0],text, sizeof(text));
      }
    Ça marche mais je comprend bien que ce n'est pas top.

    Au fait, "strncpy(temp.c_str(), text, Size);" ne compile pas avec minGW car c_str() renvoie un "const char*" alors que strncpy attend un char*.

  4. #4
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Bizarre qu'il ne déduise pas.
    Et avec un code de ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void get_value(TiXmlElement* node, const char (&array)[N])
            { /* ... */ }

  5. #5
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Salut,

    As tu, tout bêtement, essayé en précisant la taille

    Quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      char new_text[16];
      SOAPRPC::get_value<16>(pNode, new_text);
    (ou un typedef associé, why not)
    Le problème, c'est que c'est appelé par un code qui est généré automatiquement avec du gccxml. Il y a plusieurs types possibles, et je me base sur le compilateur pour faire la résolution des différentes surcharges et spécialisations.
    Citation Envoyé par Nogane Voir le message
    Bonsoir,
    Ça ne marche pas chez moi non plus. (Les deux functions en fait). Avec minGW 4.3

    La seul alternative que j'aurais serais quelque chose comme ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      template<class T>
      void get_value(const TiXmlElement* node, T text)
      {
        std::string temp = node->GetText();
        std::strncpy(&temp[0],text, sizeof(text));
      }
    Ça marche mais je comprend bien que ce n'est pas top.

    Au fait, "strncpy(temp.c_str(), text, Size);" ne compile pas avec minGW car c_str() renvoie un "const char*" alors que strncpy attend un char*.
    Tiens, bizarre que ça ne passe pas avec Mingw. Et bizarre aussi pour strncpy, puisque j'utilise les en-têtes gcc, et je n'ai pas eu de problème. Peut-être plus un bug chez eux ?
    Citation Envoyé par Alp Voir le message
    Bizarre qu'il ne déduise pas.
    Et avec un code de ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void get_value(TiXmlElement* node, const char (&array)[N])
            { /* ... */ }
    Euh... Faudra que j'essaie. Mais bon, ça ne me plaît pas trop comme écriture

  6. #6
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    J'ai oublié template <int N> biensûr dans mon code

  7. #7
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    T'as essayé ?
    Ce qui me chiffonne, c'est que le compilateur comprend bien que les deux aruments sont un const TiXmlElement* et un char[16] (par exemple), mais il n'arrive pas à instancier le code. Tu as essayé si ça marche avec ta solution ?

  8. #8
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    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
    13
    14
    15
    16
    #include <iostream>
     
    using namespace std;
     
    template <int N>
    void get_value(const char (&array)[N])
    { 
      cout << "get_value<" << N << "> called" << endl;
    }
     
    int main()
    {
      char test[10];
      get_value(test);
      return 0;
    }
    renvoie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ ./test
    get_value<10> called

  9. #9
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    OK, je vais tester ça demain

    Pourquoi il y a le (&array) ? (l'array doit être modifié, donc j'enlèverai le const )

  10. #10
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Citation Envoyé par Matthieu Brucher Voir le message
    OK, je vais tester ça demain

    Pourquoi il y a le (&array) ? (l'array doit être modifié, donc j'enlèverai le const )
    J'ai tiré l'idée d'ici : http://hermitte.free.fr/Info/C++/lib..._help.hpp.html
    Il faudra demander à Luc

  11. #11
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Ah !! Trop facile comme ça

  12. #12
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Parce qu'en argument de fonction par valeur, un tableau de taille définie ou non, ça devient en interne un pointeur.

    Code mettant ça en évidence :

    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
    void f(int i[2])
    {
    }
     
    /*void f(int i[3])
    {
    }
     
    void f(int i[])
    {
    }
     
    void f(int *i)
    {
    }*/
     
    void g(int (&i)[2])
    {
    }
     
     
    void g(int (&i)[3])
    {
    }
     
    /*void g(int (&i)[])
    {
    }*/
    Décommente une seule des fonctions f, et tu auras une erreur de fonction définie 2 fois...
    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.

  13. #13
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Décommente une seule des fonctions f, et tu auras une erreur de fonction définie 2 fois...
    Alors que ça ne sera pas le cas pour les fonctions g, c'est ça ?

  14. #14
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Parce qu'en argument de fonction par valeur, un tableau de taille définie ou non, ça devient en interne un pointeur.
    OK pour ça, il n'y a pas de problème, c'est plus la syntaxe qui m'étonnait.

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Par contre : (&array)[] ça compile pas si?


    Mais c'est vrai que cette syntaxe (je l'utilise des fois pour remplir les vector puisque ça permet de récupérer des pointeurs sur le début et la fin) m'a toujours un peu étonné...

  16. #16
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par Alp Voir le message
    Alors que ça ne sera pas le cas pour les fonctions g, c'est ça ?
    Elles sont décommentées dans l'exemple, et le code compile...

    Citation Envoyé par Goten Voir le message
    Par contre : (&array)[] ça compile pas si?
    Non, en effet (d'où le fait qu'elle soit commentée chez moi). Un tel tableau est sensé avoir une taille.
    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.

  17. #17
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Effectivement, ça fonctionne très bien. Et pour la deuxième fonction, j'imagine que c'est ma surcharge avec un std::string qui était utilisée, et non le const char[]...

    Merci pour la solution

  18. #18
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    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 397
    Par défaut
    Attention aussi avec l'emploi de strncpy() : Souviens-toi que s'il y a troncature, le buffer n'est pas terminé par un caractère nul...
    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.

  19. #19
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Tout à fait
    C'est pour ça que j'ai fini par passer un std::string, mais comme c'était un refactoring progressif, je ne voulais pas tout détruire d'un coup !

  20. #20
    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
    Dans la deuxième fonction, Size ne sert à rien...

    Et c'est bien entendu parce qu'il manquait le & que la première ne marchait pas.

    Pour le set_value tu pourrais utiliser une range, ça coûte rien.
    Pour le get_value par contre, soit tu prends un output iterator soit tu retournes une std::string.

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

Discussions similaires

  1. Taille d'une chaîne de caractères
    Par walidos11 dans le forum Assembleur
    Réponses: 1
    Dernier message: 10/11/2010, 12h09
  2. La taille d'une chaîne de caractères
    Par looking_4truth dans le forum Débuter
    Réponses: 4
    Dernier message: 09/08/2010, 15h32
  3. Taille d'affichage réel d'une chaîne de caractères
    Par SheikYerbouti dans le forum AWT/Swing
    Réponses: 5
    Dernier message: 21/02/2007, 17h46
  4. [Configuration] problème de taille de chaînes de caractères
    Par Wormus dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 8
    Dernier message: 21/10/2005, 14h55

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