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 char* (UTF-8) en wchar_t*


Sujet :

C

  1. #1
    IMS
    IMS est déconnecté
    Membre averti
    Inscrit en
    Mai 2005
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 35
    Par défaut Conversion char* (UTF-8) en wchar_t*
    Bonjour,
    Comme le titre l'indique j'ai un souci pour convertir une chaine de caractères encodée en UTF-8 en tableau de wchar_t. => j'ai lu beaucoup de choses mais je n'arrive pas à trouver la solution, un petit coup de main serait la bienvenue

    L'objectif est d'obtenir un tableau de caractères pour pouvoir ensuite accéder facilement à un caractère de la chaine par son indice (genre tab[5]).
    J'ai testé avec la fonction wmemset mais il semblerait qu'il faille modifier la locale or je sais que la chaine passée en paramètre est en UTF-8 mais je ne veux pas modifier le système.

    J'ai vu des idées du côté de iconv ou de la glib,, qu'en pensez vous ?

    Merci d'avance

  2. #2
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Modifier la locale ne veut pas dire modifier le système (voir setlocale()).

  3. #3
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    La librairie iconv est usuellement utilisée pour ça.
    Si tu cherches quelque chose de plus petit, tu peux envisager ce bout de code, gracieusement fourni par Unicode.org : ça marche très bien aussi.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  4. #4
    IMS
    IMS est déconnecté
    Membre averti
    Inscrit en
    Mai 2005
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 35
    Par défaut
    Non mais je modifie la locale du programme... il me faut donc sauvegarder la locale avant conversion et la remettre à jour après.
    J'ai testé avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char* sLocale = setlocale(LC_CTYPE, "fr_FR.UTF-8");
    Mais sLocale vaut NULL, est ce parce que la locale ne serait pas installée ?

  5. #5
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    De façon générale, il est quand même bien vu par les utilisateurs que les programmes qu'ils exécutent ne modifient pas, même temporairement, leurs réglages...

    Adaptes-toi au système de l'utilisateur, et non pas le contraire. L'OS te fournit de l'UTF-8 et tu veux de l'UTF-16 ? Fais les conversions, c'est encore le plus simple et le plus portable...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  6. #6
    IMS
    IMS est déconnecté
    Membre averti
    Inscrit en
    Mai 2005
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 35
    Par défaut
    Je suis bien d'accord avec toi pour ne pas modifier la locale.

    Je suis en train d'étudier la librairie fournie par unicode.org, çà m'a l'air de correspondre exactement à ce que je recherche. Au lieu d'utiliser des wchar, j'utiliserai des UTF32 (soit des unsigned long) => j'aurai un tableau de UTF32 et donc l'accès à mon indice se fera directement !

    A tout hasard tu n'aurais pas un exemple clair d'utilisation des méthodes de conversion car les exemples donnés dans le fichier harness.c ne sont pas vraiment lisibles...
    En entrée j'ai un char* sInput
    En sortie je dois avoir un UTF32[MaxChar] sOutput;

    Merci pour ton aide en tout cas

  7. #7
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par IMS Voir le message
    A tout hasard tu n'aurais pas un exemple clair d'utilisation des méthodes de conversion car les exemples donnés dans le fichier harness.c ne sont pas vraiment lisibles...
    En entrée j'ai un char* sInput
    En sortie je dois avoir un UTF32[MaxChar] sOutput;
    Suffit de regarder l'entête de ConvertUTF.h, en fait, y'a que quelques fonctions...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ConversionResult retval = ConvertUTF8toUTF32(&sInput,&sOutput,strictConversion);
    Pour calculer la longueur d'une chaîne UTF-8, il te suffit de la parcourir caractère par caractère, et d'appeler isLegalUTF8Sequence sur le caractère en question (faut jongler avec les pointeurs pour ça). A chaque caractère, s'il représente une séquence UTF-8 légale, la longueur est incrémentée de 1.
    Sinon, tu testes la même chose avec une séquence de deux caractères (on inclus le suivant) : si c'est bon, longueur incrémentée, sinon erreur de parsing.

    Cela donne quelque chose dans le genre (pas testé) :
    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
    size_t UTF8strlen ( const UTF8* utf8string ) {
     
      size_t result = 0 ;
      size_t len = strlen(utf8string) ;
      for (int i=0;i<len;i++) {
        if (isLegalUTF8Sequence(&utf8string[i],&utf8string[i]))
          result++ ;
        else {
          if (isLegalUTF8Sequence(&utf8string[i],&utf8string[i+1])) {
            result++ ;
            i++ ; // For skipping this 2nd character on next step.
          } else
            throw std::invalid_argument("Invalid UTF-8 string");
        }
        return result ;
    }
    Si la longueur de ta chaîne UTF-8 est inférieure ou égale à ton "MaxChar", tu peux lancer la conversion. Sinon, boum.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  8. #8
    IMS
    IMS est déconnecté
    Membre averti
    Inscrit en
    Mai 2005
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 35
    Par défaut
    Avec ton aide et la doc j'ai réussi à traiter mon problème.
    En gros cela donne :
    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
     
    //UTF32[m_iMaxChar] m_sEntry;
     
    void setValue(const char* sEntry)
    {
    	memset(m_sEntry, 0, m_iMaxChar * sizeof(UTF32));
     
    	UTF8 *utf8SourceStart, *utf8SourceEnd;
    	UTF32 *utf32TargetStart, *utf32TargetEnd;
    	utf8SourceStart = (UTF8*) sEntry;
    	utf8SourceEnd = utf8SourceStart + strlen(sEntry);
    	utf32TargetStart = m_sEntry;
    	utf32TargetEnd = utf32TargetStart + m_iMaxChar;
     
    	ConversionResult result = ConvertUTF8toUTF32((const UTF8 **)&utf8SourceStart, utf8SourceEnd, (UTF32 **)&utf32TargetStart, utf32TargetEnd, strictConversion);
    }
     
    void getValue(char* sEntry)
    {
    	UTF32 *utf32SourceStart, *utf32SourceEnd;
    	UTF8  *utf8TargetStart, *utf8TargetEnd;
    	utf32SourceStart = m_sEntry;
    	utf32SourceEnd = utf32SourceStart + m_iMaxChar-1;
    	utf8TargetStart = (UTF8*) sEntry;
    	utf8TargetEnd = utf8TargetStart + m_iMaxChar;
     
    	ConversionResult result = ConvertUTF32toUTF8((const UTF32 **)&utf32SourceStart, utf32SourceEnd, (UTF8 **)&utf8TargetStart, utf8TargetEnd, strictConversion);
    }
    J'ai quelques doutes sur les pointeurs de fin de chaine mais sinon qu'en penses tu ?

  9. #9
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par IMS Voir le message
    J'ai quelques doutes sur les pointeurs de fin de chaine mais sinon qu'en penses tu ?
    C'est surtout les pointeurs d'entrée qui m'inquiètent, pour ma part : ils sont codés en quoi ? ASCII type ISO-8859-1 ? UTF-8 ?

    Là, ton code n'indique pas vraiment quel est le format d'entrée... Or, ton "strlen" appliqué tel quel à une chaîne UTF-8 est faux, il faut utiliser une fonction telle que celle que je t'ai donnée un peu plus haut afin de tenir compte des doubles caractères.
    Et si ta chaîne est en ISO-8859-1, la fonction de conversion UTF-8 vers UTF-32 va t'exploser à la tête à cause des caractères de table ASCII étendue, qui seront vus comme des séquences UTF-8 illégales...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  10. #10
    IMS
    IMS est déconnecté
    Membre averti
    Inscrit en
    Mai 2005
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 35
    Par défaut
    Merci d'avoir jeté un oeil aiguisé sur ce bout de code !
    En effet, en entrée j'ai bien de l'UTF-8 donc strlen doit être remplacé par une méthode propriétaire...
    Quand je parlais de sortie je pensais aux buffers de fin donc utf8SourceEnd et utf32TargetEnd dans le 1er cas et utf32SourceEnd et utf8TargetEnd dans le second.

    Je posterai une solution dès qu'elle sera dispo.
    A+

  11. #11
    IMS
    IMS est déconnecté
    Membre averti
    Inscrit en
    Mai 2005
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 35
    Par défaut
    Juste pour info avant de clôturer la discussion :
    La méthode proposée UTF8strlen permet de compter le nombre de caractères de la chaine UTF-8 mais pas d'obtenir la fin du buffer de la chaine => le strlen sur un char* reste la solution la plus simple.

    Petit correctif pour compter correctement le nombre de caractères :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    if (isLegalUTF8Sequence(&utf8string[i],&utf8string[i+1]))
        result++ ;
    else {
          if (isLegalUTF8Sequence(&utf8string[i],&utf8string[i+2])) {
            result++ ;
            i++ ; // For skipping this 2nd character on next step.
          }

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

Discussions similaires

  1. conversion - char to wchar_t
    Par olobraecky dans le forum Débuter
    Réponses: 7
    Dernier message: 03/10/2008, 11h46
  2. Conversion vers UTF-8
    Par magnus2005 dans le forum Langage
    Réponses: 1
    Dernier message: 26/10/2005, 10h12
  3. Pb Invalid Conversion "char" to "char*"
    Par kazarn dans le forum C++
    Réponses: 3
    Dernier message: 02/03/2005, 13h24
  4. Conversion char * vers wchar_t
    Par Zapan dans le forum C++
    Réponses: 4
    Dernier message: 24/02/2005, 15h56
  5. Réponses: 3
    Dernier message: 26/05/2004, 23h03

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