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

Qt Discussion :

Passage d'un QString à un char* !


Sujet :

Qt

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    164
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 164
    Points : 161
    Points
    161
    Par défaut Passage d'un QString à un char* !
    salut, ma question parait simpliste mais c'est un véritable calvaire ou alors je passe à coté d'un truc.
    je dois passer mon QString en char* pour l'utiliser en argument d'une fonction (écrite en C).
    Un petit tour dans la doc Qt et on peut voir qu'il n'y a pas de fonction qui fait ça mais les méthodes data() et constdata() renvoient le contenu du QString en QChar*. Les méthodes toAcsii et toLatin1 de la classe QChar permettent de renvoyer la valeur du caractère en char.
    A partir de ce constat j'ai essayé d'écrire la fonction suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    const QChar *qchar = stringqt.constData();
    char *monchar = new char[stringqt.size()];
    for (int i=0; i<stringqt.size(); i++)
            *(monchar+i) = (qchar+i)->toAscii(); //ou ->toLatin1
     
    return monchar;
    et là j'ai bien ma chaine correspondant à mon QString mais j'ai en plus une 15aine de caractères rajoutés en fin de chaine sans raison particulière (alors que j'alloue la bonne taille) c'est vraiment bizarre?! voyez vous une faute dans l'algo?
    un moyen plus simple?
    merci

  2. #2
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    QString::toLocal8Bit()te retourne une QByteArray, soit un tableau de valeurs de 8 bits ... rien d'autre finalement qu'un tableau de char

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    QString* monString = new QString("abcdef");
    char* str = monString->toLocal8Bit().data();
    printf("mon string est: '%s'", str);
    PS: même principe pour toLatin1 et toAscii.
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  3. #3
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Salut
    Tu peut aussi passer par une std:: string :
    http://qt.developpez.com/doc/4.4/qstring/#tostdstring

    Attention au problème d'encodage. toLocal8Bit est surement le plus adapté
    http://qt.developpez.com/doc/4.4/qstring/#tolocal8bit

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    164
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 164
    Points : 161
    Points
    161
    Par défaut
    merci pour vos réponses, j'ai des résultats très louches :
    -comme je l'ai dit la fonction que j'ai écrit fonctionne mais la chaine comporte des caractères en plus (des caractères bizarre î etc)
    -la méthode proposée avec toLocal8Bit() me donne en sortie une chaine très longue avec des caractères bizarres

    - la seule chose qui marche est de passer par toStdString().data()

    les mystères de l'informatique...

    peut-etre y-a t'il des réglages à faire au niveau des jeux de caractères ?

  5. #5
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Aucun mystère à cela, la doc Qt est explicite sur le sujet:

    The returned byte array is undefined if the string contains characters not supported by the local 8-bit encoding.
    Pour convertir un caractère qui n'a pas d'équivalent en ascii, il te faudra passer par un QTextCodec.
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    164
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 164
    Points : 161
    Points
    161
    Par défaut
    - le tableau retourné n'est pas "undefined" mais comporte bien environ un millier de caractères : des î et un symbole que je n'ai jamais vu avant

    - ça n'explique pas non plus les résultats que j'obtiens par la méthode que j'ai proposé

  7. #7
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Citation Envoyé par atomicJo Voir le message
    - le tableau retourné n'est pas "undefined" mais comporte bien environ un millier de caractères : des î et un symbole que je n'ai jamais vu avant
    Quand la doc dit "The returned byte array is undefined", ça veut dire que le contenu du tableau n'est pas prévisible et donc que les données qu'il contient ne correspondent à rien d'utilisable par l'appelant de la fonction. Ici, 'undefined' doit s'interpréter comme 'imprévisible' (unpredictable), pas que le tableau contient la valeur 'undefined'
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  8. #8
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    - ça n'explique pas non plus les résultats que j'obtiens par la méthode que j'ai proposé
    Tu veux faire le malin avec les pointeurs ... mais qui fait le malin tombe dans le ravin comme dirait l'autre
    Au lieu de vouloir faire le kakou avec les pointeurs, autant revenir sur les bases, explicites dans le code et faciles à relire, ici aussi rapides à exécuter, et bien moins sujettes à erreur ; les relecteurs t'en remercieront

    Et puis tant qu'à faire, on va la faire s'arrêter quelque part cette chaine de caratères, ce qui a quand même de bonnes chances de résoudre ton souci. Avec un caractère '\0' par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    char *monchar = new char[stringqt.size()+1];
    monchar[stringqt.size()] = '\0';
     
    for (int i=0; i<stringqt.size(); i++) {
        monchar[i] = qchar[i].toAscii();
    }
    EDIT: de façon plus générale, il ne faut pas prendre les compilateurs pour plus abrutis qu'ils ne sont: les compilateurs récents sont capable de mettre en oeuvre eux-même la plupart des optimisations simples, cf. les options d'optimisation de gcc par exemple.
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    164
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 164
    Points : 161
    Points
    161
    Par défaut
    faire le malin avec les pointeurs ahah faudrait vraiment avoir que ça à foutre...

    j'avais tenté également le coup du caractère de fin de chaine mais ça ne change rien exepté le fait que le "î" se trouvant à cette position est remplacé par un zéro, les 15 caractères suivants "imprédictibles" subsistent
    et donc je ne comprends pas vraiment ce qui se passe..

  10. #10
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    j'avais tenté également le coup du caractère de fin de chaine
    C'est pas une histoire de 'tenter le coup': ce caractère est indispensable à la fin de toute chaîne de caractère stockée dans un char*.
    Au passage, si tu as des caractères qui sont affichés par un printf après le fameux caractère '\0', c'est que tu a raté un truc: as-tu bien affecté le caractère '\0' (caractère non affichable NUL d'où le backslash, code décimal = 0) et pas le caractère '0' (caractère affichable zéro, code décimal 48) ?
    Au passage, ce sont des zéros, pas des lettres 'O'.

    Tu peux nous montrer un exemple concret complet avec les adaptations (printf, ...) que tu as faites, avec le contenu d'une string concrète qui ne marche pas et le résultat que ça te donne ?
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  11. #11
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Tu n'essaierais pas de te servir des données retournées par QString::to* alors que l'instance est détruite par hasard ? (retour de fonction, paramètre en sortie qui fait une simple assignation au lieu d'une copie etc...)

  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    164
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 164
    Points : 161
    Points
    161
    Par défaut
    arg faute toute con j'avais essayé '/0' et non pas '\0' ..
    maintenant le code suivant fonctionne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    QString strqt="abcdef";
    const QChar *qchar = strqt.constData();
    char *monchar = new char[strqt.size()+1];
    monchar[strqt.size()] = '\0';
     
    for (int i=0; i<strqt.size(); i++)
    	monchar[i] = qchar[i].toAscii();
    reste que le bout de code que m'a proposé nouknouk c'est à dire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    QString* monString = new QString("abcdef");
    char* str = monString->toLocal8Bit().data();
    me donne la chaine suivante (attention aux yeux):
    îþîþîþîþîþîþîþîþîþîþî........îþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþä*º
    Les points sont là pour racourcir, il y a environ un millier de caractères!
    Pourtant la chaine ne comporte pas de caractère non ascii
    (je visualise le contenu du char* non pas par un printf (j'ai pas de console) mais en mode debug avec un point d'arret à la ligne suivante avec le visualiseur de texte.)

  13. #13
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    le retour de .data() ne contient pas le \0 si je ne me trompe pas

  14. #14
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    QString* monString = new QString("abcdef");
    char* str = monString->toLocal8Bit().data();
    Comme le disait IrmatDen, il est probable que ce soit à cause de la destruction immédiate de la QByteArray créée par toLocal8bit() juste après l'appel à la fonction data.
    Les caractères "îþ" que tu as correspondent d'ailleurs aux codes "FE EE" qui - si je me souviens bien - sont les caractères de remplissage que le débugueur assigne (en mode debug uniquement) lorsqu'il désalloue une zone mémoire (ça permet de voir facilement quand on tape dans une zone mémoire qui a déjà été libérée).

    Tu peux essayer comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    QString* monString = new QString("abcdef");
    QByteArray* array = new QByteArray(monString->toLocal8Bit());
    array->resize(array->size()+1);
    (array->data())[array->size()-1] = '\0';
    char* str = array->data();
    sinon, tu peux essayer avec les autres fonction (toAscii, ...).
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  15. #15
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par nouknouk Voir le message
    Il est probable que ce soit à cause de la destruction immédiate de la QByteArray créée par toLocal8bit() juste après l'appel à la fonction data.
    Ha oui, j'y avais pas pensé. Y as des chances que ce soit lié à cela aussi.

    Sinon pour utiliser QByteArray dans ton exemple, y as peut l'intérêt à utiliser un pointeur

  16. #16
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Citation Envoyé par yan Voir le message
    Sinon pour utiliser QByteArray dans ton exemple, y as peut l'intérêt à utiliser un pointeur
    Effectivement, ma méthode est des plus bourrine. Mais pour un simple test, qui peut le plus peut le moins, et vu qu'à la dernière solution proposée on a du insister pour l'histoire du '\0', je préfère prendre les devants
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  17. #17
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    164
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 164
    Points : 161
    Points
    161
    Par défaut
    Si le .data() gère automatiquement l'ajout du caractère de fin de chaine, je viens de tester et le code suivant marche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    QString* monString = new QString("abcdef");
    QByteArray* array = new QByteArray(monString->toLocal8Bit());
    char* str = array->data();
    Le problème venait donc bien de la destruction immédiate du tableau de bytes renvoyé par .toLocal8Bit()

    merci à tous c'est réglé

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

Discussions similaires

  1. Convertir char vers QString
    Par darkwall_37 dans le forum Débuter
    Réponses: 3
    Dernier message: 25/05/2009, 11h49
  2. Formatage lors du passage d'un type NUMBER à un type CHAR
    Par LARS14 dans le forum Langage SQL
    Réponses: 5
    Dernier message: 29/08/2008, 16h20
  3. Conversions implicites de QString en const char*
    Par mister3957 dans le forum C++
    Réponses: 3
    Dernier message: 22/08/2008, 17h27
  4. passage de char en int
    Par liverbird dans le forum C++
    Réponses: 5
    Dernier message: 21/01/2008, 16h07
  5. Conversion QString en char*
    Par Stage2006 dans le forum Qt
    Réponses: 5
    Dernier message: 12/06/2007, 17h14

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