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

Delphi Discussion :

[Unicode] Comment lire des caractères ?


Sujet :

Delphi

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 35
    Points : 27
    Points
    27
    Par défaut [Unicode] Comment lire des caractères ?
    Bonjour

    J'ai un souci avec l'unicode.

    J'ai un fichier avec une chaîne de caractère (en unicode), par exemple :

    Essai avec les accents : à â é è ê ù û i î

    Mon code actuel est le suivant :

    var
    FS : TFileStream;
    buf : pChar;
    sChaine : WideString;

    begin
    ...
    buf := pChar(AllocMem(pEntree^.size + 1));
    FS.Read(buf^, pEntree^.size);
    sChaine := buf;
    ...
    Lorsque j'affiche sChaine, la valeur est la suivante :

    Essai avec les accents : à â é è ê ù û i î

    J'ai bien tenté de convertir mon code en ceci :

    var
    FS : TFileStream;
    buf : pWideChar;
    sChaine : WideString;

    begin
    ...
    buf := pWideChar(AllocMem(pEntree^.size + 1));
    FS.Read(buf^, pEntree^.size);
    sChaine := buf;
    ...
    Mais le résultat est plutôt douteux :

    ?????????????????????????

    Sauriez vous par hasard comment lire de l'unicode dans un fichier ?

    Si oui, pouvez vous m'indiquez des exemples, où mieux, me dire ce que je dois faire dans mon code pour pouvoir convertir des caractères unicodes ?

    En vous remerciant par avance.
    Mickey974

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Essaye de voir avec la fonction Utf8ToAnsi

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 35
    Points : 27
    Points
    27
    Par défaut
    Merci pour ta réponse ShaiLeTroll, hélas rien n'y fait.

    Ni Utf8ToAnsi, ni DecodeUtf8, ni des trucs exotiques comme :

    sChaine := WideString(WideCharLenToString(buf,pEntree^.size));

    J'avoue être un peu coincé là ...

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    as essayé d'utiliser le fonction de lecture de fichier pascal genre blockread, et tu déclare comme buf un widestring

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    var
      Buf: WideString;
    Reset(BinaryFile, 2);
    ...
    SetLengh(Buf, len);
    BlockRead(BinaryFile, Buf[1], len);  ...
    je n'ai pas testé !

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 35
    Points : 27
    Points
    27
    Par défaut
    Bonjour

    J'ai essayé ton code ... pas de résultat concluant. Par contre j'ai parcouru pas mal de forum et il en ressort qu'une chaîne dans un fichier peut être un mélange de caractère ASCII (8 bits) et UNICODE (16 bits ou +)

    La problèmatique est donc de faire la distinction entre ces deux type de caractères car sinon c'est le gros bazard. Bref, j'ai construit rapidement dans mon application un morceau de code afin de faire cette disctinction.

    Si j'arrive effectivement à faire le distinguo entre les deux types de caractères en provenance d'une même chaîne, néanmoins, je suis incapable d'afficher les caractères unicode. J'ai beau essayé toutes les fonctions à ma disposition dans Delphi et cela ne fonctionne pas du tout.

    Voici mon bout de code :
    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
    29
    30
    31
    32
    33
     
    var
       d1,d2,d3     : int64;
       FS             : TFileStream;
       buf            : pChar;
       pos            : int64;
       chaine1      : pWideChar;
       chaine2      : WideString;
       sChaine      : WideString;
     
    ...
    d1 := FS.Position;
    FS.Read(buf^, pEntree^.size);
    d3 := FS.Position;
    sChaine := '';
    chaine2 := '';
    pos := 0;
    chaine1 := pWideChar(AllocMem(SizeOf(WideChar) + 1));
    while pos < pEntree^.size do begin
       if Ord(buf[pos]) < 128 then begin
          chaine2 := chaine2 + buf[pos];
          Inc(pos);
       end else begin
          FS.Seek(d1 + pos,soFromBeginning);
          FS.Read(chaine1^,sizeof(WideChar));
          chaine2 := chaine2 + chaine1;
          pos := pos + 2;
       end;
     
    end;
     
    FS.Seek(d3,soFromBeginning);
    ...
    Je récupère en sortie selon les composants :

    - TVirtualStringTree : Essai avec les accents : ? ? ? ? ? ? ? i ?
    - TTntMemo : Essai avec les accents : _ _ _ _ _ _ _ i _

    C'est pas génial ! On se demande si ces composants sont véritablement UNICODE ! Un WideString c'est bien une chaîne unicode ou alors j'ai rien capté ?

  6. #6
    Membre du Club Avatar de papadrago
    Inscrit en
    Juillet 2006
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 59
    Points : 45
    Points
    45
    Par défaut
    On se demande si ces composants sont véritablement UNICODE
    Delphi ne permet pas d'afficher de l'Unicode directement. C'est un des gros reproches qu'on lui fait. On peut y arriver quand même en utilisant des composants tiers. A ma connaissance, il y a 3 solutions :



    J'ai testé utf8vcl et son fonctionnement tient de la magie : un simple "uses utf8vcl" et une appli se met à afficher de l'unicode (j'ai essayé avec du chinois) . Seul inconvénient, elle est en développement et quelques composants sont manquants (THeaderControl, TPageControl).

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 35
    Points : 27
    Points
    27
    Par défaut
    je te remercie papadrago pour tes url. je vais aller jetter un oeil sur cette librairie en OpenSource.

    Par contre en lisant ce que tu dis à propos de l'unicode et des composants ... je suis sur l'expectative. Lorsque tu regardes des composants comme TVirtualStringTree, son concepteur affirme sur son site qu'il est unicode.

    http://www.soft-gems.net/index.php?o...d=12&Itemid=33

    Quand à TTntMemo que j'utilise, il affiche carrément dans la fenêtre de l'éditeur intégré un petit unicode en vert sur la fenêtre de l'éditeur d'ajout de ligne.

    Pourquoi donc cela ne fonctionne-t-il pas ? Ai je omis quelque chose quelque part ?

    Bref ... j'ai continué à explorer un peu plus ce problème et j'ai réussi malgré tout à traduire ces caractères. Voici donc le bout de code qui le fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    ...
                  FS.Read(buf^, pEntree^.size); 
                  pos := 0; 
                  while pos < pEntree^.size do begin 
                      if Ord(buf[pos]) < 128 then begin 
                      sChaine := sChaine + WideChar(buf[pos]); 
                      Inc(pos); 
                      end else begin 
                        sChaine := sChaine + Utf8ToAnsi(buf[pos] + buf[pos + 1]); 
                        pos := pos + Sizeof(WideChar); 
                      end; 
                  end; 
    ...
    le résultat : Essai avec les accents : à â é è ê ù û i î

    Par contre, cette méthode (bidouille plutôt ) ne permet pas de connaître le type d'encodage du caractère. Donc pour de l'UTF8 2 octets ca fonctionne, mais comment savoir si c'est bien de l'UTF8 ? Certes on teste les bits de poids forts ... mais ... mais ... mais, l'UTF8 dans la norme peut se coder sur 1,2,3,4 octets max ! Et si c'est de l'UTF16 ou 32, je n'en parle même pas, comment faire ?

    Comment tester le type d'encodage d'un caractère ? Voila en fait mon souci maintenant.

    Désolé, je débute ... dans l'unicode

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 35
    Points : 27
    Points
    27
    Par défaut
    Petite amélioration ... UTF8 1, 2, 3 4 octets

    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
     
    ...
                   while pos < pEntree^.size do begin
                      // UTF-8
                      if Ord(buf[pos]) < 128 then begin
                      sChaine := sChaine + WideChar(buf[pos]);
                      Inc(pos);
                      end else begin
                         if ((ord(buf[pos]) shr 4)  = 15) then begin
                            // codé sur 4 octets
                            sChaine := sChaine +
                               Utf8ToAnsi(buf[pos] + buf[pos + 1] + buf[pos + 2] +
                                          buf[pos + 3]);
                            pos := pos + 4;
                         end else if (ord(buf[pos]) shr 5  = 7) then begin
                            // codé sur 3 octets
                            sChaine := sChaine +
                               Utf8ToAnsi(buf[pos] + buf[pos + 1] + buf[pos + 2]);
                            pos := pos + 3;
                         end else if (ord(buf[pos]) shr 6  = 3) then begin
                            // codé sur 2 octets
                            sChaine := sChaine +
                               Utf8ToAnsi(buf[pos] + buf[pos + 1]);
                            pos := pos + 2;
                         end;
                      end;
                   end;
    ...
    Manque plus que UTF16-BE, UTF16-LE, UTF32 ...

Discussions similaires

  1. comment imprimer des caractères Unicode dans Matlab
    Par kruskal21 dans le forum MATLAB
    Réponses: 1
    Dernier message: 24/01/2011, 16h19
  2. [Excel] Comment lire des fichiers excel avec php?
    Par dear_rihab dans le forum Bibliothèques et frameworks
    Réponses: 5
    Dernier message: 02/11/2007, 12h38
  3. Réponses: 3
    Dernier message: 27/06/2005, 16h24
  4. Comment extraire des caractères d'une chaine ?
    Par Powa87 dans le forum Langage
    Réponses: 16
    Dernier message: 01/01/2005, 19h00
  5. CFile : comment lire des données
    Par romeo9423 dans le forum MFC
    Réponses: 3
    Dernier message: 25/10/2004, 19h10

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