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 :

convertir un ansistring en const char*


Sujet :

C++

  1. #1
    Membre habitué
    Inscrit en
    Juin 2007
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 362
    Points : 141
    Points
    141
    Par défaut convertir un ansistring en const char*
    Bonjour,

    dans mon soft, j'utilise une base de données mysql, aussi j'ai créé un système de dump et de restauration.

    pour la restauration je passe par la commande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    system(const char * valeur);
    Le hic, c'est que je récupère le chemin d'accès de mon fichier sql dans une variable de type String ou AnsiString.

    donc ce n'est pas compatible avec ce qu'a besoin la commande "system" où il faut du Const char *.

    Ma question est la suivante, comment dois je convertir mon String en Const char * ?

    merci d'avance

  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
    Points : 13 017
    Points
    13 017
    Par défaut

  3. #3
    Membre habitué
    Inscrit en
    Juin 2007
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 362
    Points : 141
    Points
    141
    Par défaut
    Merci !

    J'ai complètement zappé de regarder dans la FAQ..... et surtout de faire sur BCB ^^

    En tout cas voici le code pour ceux qui auraient été ou seront dans cet embarras:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    chemin = "C:\\mysql\\bin\\mysql maBase< ";
    chemin += valRoot;  //chemin d'accès du fichier sql vennant du dump
    char * cmd = new char[chemin.Length()+1];
    strcpy(cmd,chemin.c_str());
    system(cmd);

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    N'aurait-il pas été plus simple de faire juste:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    chemin = "C:\\mysql\\bin\\mysql maBase< ";
    chemin += valRoot;  //chemin d'accès du fichier sql vennant du dump
    system(chemin.c_str());
    ?
    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.

  5. #5
    Membre habitué
    Inscrit en
    Juin 2007
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 362
    Points : 141
    Points
    141
    Par défaut
    effectivement, j'ai préféré faire un code plus orienté "usine à gaz" afin, lors de mon passage en mode pas à pas, que je puisse vérifier que la conversion se passe bien, et qu'aucun caractère n'ai été altéré.

  6. #6
    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
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    N'aurait-il pas été plus simple de faire juste:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    chemin = "C:\\mysql\\bin\\mysql maBase< ";
    chemin += valRoot;  //chemin d'accès du fichier sql vennant du dump
    system(chemin.c_str());
    ?
    Si on n'en croit la FAQ, non, car le pointeur est temporaire:
    Citation Envoyé par F.A.Q.
    Attention ! La méthode c_str retourne un pointeur sur une chaîne C, qui n'est valable que pour l'instruction suivant l'appel à c_str. En d'autres termes, vous ne pouvez pas faire ceci :

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Les temporaires vivent au moins jusqu'au retour d'une fonction à laquelle ils sont transmis en argument, non?

    En supposant que la fonction system() ne modifie pas elle-même la string, bien entendu.
    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.

  8. #8
    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
    Points : 4 625
    Points
    4 625
    Par défaut
    char * cmd = new char[chemin.Length()+1];
    strcpy(cmd,chemin.c_str());
    Tu peux faire un memcpy ici (voire même un memcpy aligné), ça ira plus vite.
    Boost ftw

  9. #9
    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
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Les temporaires vivent au moins jusqu'au retour d'une fonction à laquelle ils sont transmis en argument, non?

    En supposant que la fonction system() ne modifie pas elle-même la string, bien entendu.
    Pas tout à fait, la temporaire peut te donner accès à un buffer qui pourra être réutilisé plus tard. C'est pourquoi tu dois recopier la valeur tout de suite. J'avais eu des problèmes de ce genre avec ILog (j'avais pas choisi d'utiliser cette librairie, donc par avance éviter les trolls!): tu récupères une adresse et à l'appel suivant, l'adresse est encore valide mais les données ne le sont plus!

  10. #10
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    L'adresse fournie par .c_str() est l'adresse de la chaine de caractère dans l'objet std::string.

    La seule chose que peut changer c_str(), c'est de rajouter le caractère nul '\0' à la fin. (pas rajouter, mais en fait changer le caractère après le dernier caractère lisible)

    La string n'est pas modifiée pendant l'appel à system (ce n'est pas un programme multithread qui partage la variable chemin ??), donc il n'y a aucun risque à utiliser .c_str()...

    Le pointeur a beau être temporaire, l'adresse sur laquelle il pointe ne l'est pas, et la valeur du pointeur (c'est à dire l'adresse) ne change pas, même s'il est temporaire...

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Attention, il ne s'agit apparemment pas d'une std::string, mais comme le titre du thread l'indique, d'une AnsiString Borland.
    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.

  12. #12
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Attention, il ne s'agit apparemment pas d'une std::string, mais comme le titre du thread l'indique, d'une AnsiString Borland.
    Ah d'accord

    Mais s'il y a un risque pour que la mémoire soit écrasée entre .c_str() et la fin de l'appel à system:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    system(chemin.c_str());
    Il y a aussi un risque pour qu'elle soit écrasée entre .c_str() et la fin de l'appel à strcpy non?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char * cmd = new char[chemin.Length()+1];
    strcpy(cmd,chemin.c_str());
    A moins que l'appel à system risque d'écraser l'emplacement mémoire et pas l'appel à strcpy

  13. #13
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Si on n'en croit la FAQ, non, car le pointeur est temporaire:
    En fait non, la FAQ dit que ce code risque de planter:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    AnsiString Src = "Source.txt";
    AnsiString Dest = "Destination.txt";
    char * pSrc = Src.c_str();
    char * pDest = Dest.c_str();
    // instructions
    CopyFile(pSrc,pDest,true);
    A cause de //instructions. La solution avec le strcpy est proposée dans le cas où il y a des instructions entre l'appel à .c_str() et à la fonction concernée.

  14. #14
    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
    Points : 13 017
    Points
    13 017
    Par défaut
    Je ne connais pas AnsiString, mais comme j'avais eu un pb similaire avec Ilog, j'ai vu la chose comme ça. D'ailleurs, si on reprend la FAQ:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    AnsiString Src = "Source.txt";
    AnsiString Dest = "Destination.txt";
    char * pSrc = Src.c_str();
    char * pDest = Dest.c_str();
    CopyFile(pSrc,pDest,true);
    Entre pSrc = Src.c_str() et CopyFile(pSrc,..., il y a pDest = Dest.c_str();. Donc à priori, on pourrait avoir la même adresse, la chaîne ayant changée entre pSrc.c_str et pDest.c_str, non? D'où la solution préconisée dans la FAQ de faire une copie de la chaîne obtenue avec c_str() tout de suite!

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

Discussions similaires

  1. conversion AnsiString en const char*
    Par Mangacker dans le forum C++Builder
    Réponses: 3
    Dernier message: 14/05/2007, 18h43
  2. Réponses: 3
    Dernier message: 25/10/2006, 22h54
  3. Convertir un "char" en "CONST char"
    Par N3odyme dans le forum C
    Réponses: 3
    Dernier message: 17/08/2006, 19h48
  4. Réponses: 6
    Dernier message: 28/10/2005, 12h11
  5. Réponses: 13
    Dernier message: 06/03/2005, 15h21

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