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 Delphi Discussion :

Traitement unicode et Language europe de l'Est.


Sujet :

Langage Delphi

  1. #1
    Membre confirmé

    Inscrit en
    Novembre 2002
    Messages
    748
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 748
    Points : 500
    Points
    500
    Par défaut Traitement unicode et Language europe de l'Est.
    Bonjour à tous,

    J'ai une application qui a été développée avant la standardisation de l'Unicode dans delphi, et qui n'a connu que des langages latin ou anglo-saxon.
    Aujourd'hui on me demande de traiter du cyrillique. Grace aux évolutions de delphi (Unicode) dans ce domaine, il me semble que tous cela se passe bien en terme d'IHM (affichage dans les composants, copier/coller car j'ai pas de clavier pour tester, mais je suis confiant).

    Par contre pour les enregistrements ce n'est pas si simple. Ils existent pour typer les fichiers qui reçoivent ses informations. Et ce type d'enregistrement ne peut contenir que des ShortString?

    voici un exemple d'un des enregistrement
    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
    Type
        Tabletransco = record
            ConFTypeCarte  : integer;
            ConFslot       : string[10];
            ConFabrevia    : string[10];
            ConFmax        : integer;
            ConFmin        : integer;
            ConFChampPt    : string[15];
            ConFcouleur    : Tcolor;
            Ptsys          : string[6];
            PtTmux         : string[10];
            Ptinter        : string[50];
            PtTrans        : string[50];
            Equi           : string[50];
            Info           : string[100];
     
            Ptcouleur: string[17];
        end;
     
    var
        info_transco: Tabletransco;
        FTrancodage: file of Tabletransco;

    Dans ces enregistrements, certaines variables de type "shortstring" reçoivent des textes en cyrillique, donc elles doivent savoir le gérer.

    Donc voici mes questions :

    1. J'ai du mal à m'y retrouver dans les différences entre UnicodeString, AnsiString, WideString et leur compatibilité.Comment convertir les "string[xx]" en Unicode ?

    Mes hypothèses :

    1. Changer dans l'enregistrement le type (short)string et UnicodeString, mais ce nouveau type sera t-il rétro-compatible avec mes anciens fichiers ? j'en doute !
    2. Créer un second enregistrement identique mais avec des strings Unicode et mettre en place le moyen d’identifier quel enregistrement des deux utiliser pour ouvrir le fichier visé ?
    3. d'autres solutions ?

    merci a vous .
    Bye et bon code...

    Ce n'est pas tant l'aide de nos amis qui nous aide , mais notre confiance dans cette aide .

  2. #2
    Membre expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Points : 3 614
    Points
    3 614
    Par défaut
    Bonjour

    La ligne
    FTrancodage: file of Tabletransco;
    rend ton code incompatible avec des mélanges entre Unicode / UTF-8 ou 16 et ANSI.

    Si tu utilises des chaînes dans tes RECORD tu fais en fait des tableaux de caractères qui correspondaient anciennement à des octets.

    1 caractère = 1 octet était valable en ANSI mais ne l'est plus en Unicode / UTF

    Et là où ça se complique c'est qu'un caractère peut-être de 1 à 4 octets selon l'encodage choisi.

    Il est donc à mon avis impératif pour toi de modifier la façon dont tu gères tes stockages de données si tu veux pouvoir y stocker autre chose que de l'ANSI

  3. #3
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    pour compléter la réponse de Patrick, les string[x] sont des ShortString, c'est à dire un tableau de x + 1 octets avec en position 0 la longueur utile de la chaîne.

    depuis 2009 les chaînes possèdent une page de code...mais pas les ShortString qui sont traitées systématiquement avec la page de code Windows en cours (1252 pour les français).

    du coup si tu utilises ton record sur un Windows Français c'est transparent, si tu utilises ton record sur un Windows en cyrillique, ça va aussi fonctionner, mais le fichier de l'un ne pourra pas être correctement lu par l'autre.

    si tu dois supporter les deux pages de codes dans la même appli, tu dois forcément modifier ton fichier (ou à défaut son nom) pour savoir quelle page de code est utilisée...ensuite tu peux jouer avec la variable DefaultSystemCodePage pour lire le fichier dans la bonne page de code, ou en passant par exemple par TMarshal.ReadStringAsAnsi.

    sinon il faut remplacer test "string[x]" par des "array[0..x-1] of Char", soit avec un #0 terminal, soit avec un champ longueur...mais ton fichier utilisera des Chars 16bits et ne sera pas compatible avec l'existant.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  4. #4
    Membre confirmé

    Inscrit en
    Novembre 2002
    Messages
    748
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 748
    Points : 500
    Points
    500
    Par défaut
    bonjour a vous deux...

    Je m'attendais à vos réponses... mais au cas ou une astuce avait existé !!

    La solution que j'ai retenue est :

    1. Doubler tous mes "Record". On dira un ancien avec des chaines "AnsiString" et un nouveau avec des chaines "Unicode".
    2. Toutes les sauvegardes des fichiers seront faite à partir la version suivante et basées sur le nouveau Record (Unicode).
    3. Les anciens fichiers seront ouverts avec l'ancien "Record" compatibilité oblige, d’où la coexistence.
    4. Il me reste à arriver à détecter ou déterminer le type de fichier à l'ouverture, Unicode ou pas pour sélection le bon record. je peux en effet le traiter avec la date courante du logiciel
    Néanmoins , les fichiers peuvent se balader d'un pays à l'autre, donc pas optimal.

    voici mes nouvelles déclarations de Record:
    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
     
    // exemple ancien type
    Type
        TableOldInfo = record
            Info1  : integer;
            Info2  : string[10];
    end;
    var
        Oldinfo: TableOldInfo;
        FOldInfo: file of TableOldInfo;
     
     
    // exemple nouveau type
    Type
        TableNewInfo = record
            Info1  : integer;
            Info2  : array [0..10] of WideChar;
    end;
    var
        Newinfo: TableNewInfo;
        FNewInfo: file of TableNewInfo;
     
    // ensuite lors de l'ecriture  
    StringToWideChar(TabInfo.cells[1,boucle], Newinfo.Info2,10);
     
    // et de la lecture  
    TabInfo.cells[1, boucle] := WideCharToString(NewInfo.Info);
    Cela semble fonctionner , est ce la bonne voie !! un conseil ..?

    Par contre je constate que dans cette instruction : StringToWideChar(TabInfo.cells[1,boucle], Newinfo.Info2,10), si ta taille de la chaine est égale ou supérieure au nombre d'élément du tableau de caractères, les 1er caractères ne sont pas rempli et le tableau reste vide.
    Je vais me pencher dessus.
    Bye et bon code...

    Ce n'est pas tant l'aide de nos amis qui nous aide , mais notre confiance dans cette aide .

  5. #5
    Membre expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Points : 3 614
    Points
    3 614
    Par défaut
    En fait, si tu en as techniquement la possibilité, je dirais qu'il vaudrait mieux éliminer les RECORD pour le stockage en fichier et passer par des bases SQL ou du stockage en JSON, ça te permettrait de t'épargner les soucis de stockage/conversion/etc.

    Dans Delphi tu peux modifier tes RECORD pour enlever la taille ce qui permettra de travailler en Unicode.

    Les seules procédures à modifier seraient le chargement et le stockage de tes fichiers et/ou leur parcourt selon comment tu gères ça. Le reste du code peut continuer de façon transparente à travailler sur les record, les accès fichiers feraient une conversion vers ton nouveau format de stockage à l'ouverture des fichiers existants puis tu travaillerais sur les nouveaux.

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 534
    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 534
    Points : 25 082
    Points
    25 082
    Par défaut
    le BOM UTF8 ou UTF16 serait une bonne pratique pour vérifier le type de record à utiliser, plus fiable que le nom (ou extension) du fichier

    tu ne pourrais plus faire de file of TableOldInfo mais un TFileSteam et un Read, cela permettra de plus d'envisager une structure évolutive du fichier

    Attention à string[10] et array [0..10] of WideCharstring est indicé de 1 à 10
    array est indicé de 0 à 9, le 10 DOIT être un Zéro terminal, ne pas oublier cela dans les manipulations, bien vérifier si les fonctions utilisent un count AVEC ou SANS le zéro terminal
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    sur les fichiers structurés il est aussi courant d'utiliser le premier record comme entête de fichier, c'est à dire que le premier enregistrement doit avoir exactement la même taille que le record, mais il contient des informations d'une autre nature : version du fichier, nombre d'enregistrements, adresse du premier supprimé...
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

Discussions similaires

  1. Réponses: 1
    Dernier message: 27/10/2017, 13h20
  2. [PHP 5.4] traitement un fichier TXT dés qu'il est crée
    Par aspkiddy dans le forum Langage
    Réponses: 5
    Dernier message: 15/04/2015, 21h23
  3. Réponses: 1
    Dernier message: 18/08/2009, 07h59
  4. caracteres d'europe de l'est dans une JTABLE
    Par openWorld dans le forum Composants
    Réponses: 3
    Dernier message: 10/05/2007, 08h07
  5. quel est le Meilleur language pour piloter le port serie ?
    Par flyfab dans le forum Langages de programmation
    Réponses: 7
    Dernier message: 21/07/2003, 10h03

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