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 :

Transtypage de string en shortstring


Sujet :

Delphi

  1. #1
    Membre éprouvé
    Avatar de Aooka
    Homme Profil pro
    Scripting Powershell & Wlangage
    Inscrit en
    Juillet 2015
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Scripting Powershell & Wlangage

    Informations forums :
    Inscription : Juillet 2015
    Messages : 227
    Points : 1 095
    Points
    1 095
    Par défaut Transtypage de string en shortstring
    (Re-)Bonjour,


    Je voudrais simplement savoir comment mon TEdit.text ou encore mon TLabel.Text puisse prendre un ShortString plutot que du String ?

    Mon erreur :
    Nom : transtypage.png
Affichages : 765
Taille : 7,3 Ko


    Je vous remercie d'avance,
    Bonne soirée,

  2. #2
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    Bonjour !

    J'ai un peu de mal à saisir le sens de la question. Le titre fantaisiste de la discussion ne nous aide pas beaucoup non plus.

    Je suggère que tu postes les lignes de code qui sont à l'origine de l'avertissement.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 631
    Points : 10 558
    Points
    10 558
    Par défaut
    Ce n'est pas possible

    Un ShortString est un type obsolète qui correspond soit à de l'ASCII, soit à un code page/ MBCS

    Un String, c'est de l'UTF-16.

    Il faut convertir ta chaîne de caractères en UTF-16. Je ne connais pas l'API Delphi pour cela

    Ou éventuellement dans les options de ton projet, caster _TChar (*) en char et non pas en wchar_t.


    Et la meilleure de toutes, c'est de refactoriser ton code en n'utilisant que des UnicodeString.



    * -> Avec Xe, l'option s'appelle "_TChar maps to"

  4. #4
    Membre éprouvé
    Avatar de Aooka
    Homme Profil pro
    Scripting Powershell & Wlangage
    Inscrit en
    Juillet 2015
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Scripting Powershell & Wlangage

    Informations forums :
    Inscription : Juillet 2015
    Messages : 227
    Points : 1 095
    Points
    1 095
    Par défaut
    Salut,



    J'étais dans la précipitation pour écrire mon message ce jour là, c'est pourquoi pas tout très explicite. En gros je voulais mettre un ShortString dans un text de TLabel (qui demande du String).
    Mais du coup, foetus à parfaitement répondu à ma demande. Je t'en remercie.

    Mais par contre String n'est qu'un alias d'UnicodeString à a connaissance, donc qu'est-ce que ça changerais de changer mes String en UnicodeString ?



    Merci, bonne journée.

  5. #5
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par Martin Lestas Voir le message
    En gros je voulais mettre un ShortString dans un text de TLabel (qui demande du String).
    Ça, c'est possible :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    var
      s: shortstring;
    begin
      s := 'Martin';
      Label1.Caption := string(s);
    end;
    Mais l'avertissement que tu as reproduit dans ton premier message correspond à une tentative de conversion dans le sens inverse.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var
      s: shortstring;
    begin
      s := Label1.Caption;
    end;
    C'est dans ce sens-là qu'il y une "perte de données potentielle".
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  6. #6
    Membre éprouvé
    Avatar de Aooka
    Homme Profil pro
    Scripting Powershell & Wlangage
    Inscrit en
    Juillet 2015
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Scripting Powershell & Wlangage

    Informations forums :
    Inscription : Juillet 2015
    Messages : 227
    Points : 1 095
    Points
    1 095
    Par défaut
    Merci pour ta réponse,


    Bon, en fin de compte c'est pas bien utile de caster du ShortString vers du String. Je ne vais pas gagner de mémoire ? Vu que je vais revenir en String dans tout les cas.

    Oui, fuite de mémoire possible, mais dans mon cas impossible vu que je gère que mes textes ne fassent pas plus de 255 caractères, donc sa passe pile.

  7. #7
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par Martin Lestas Voir le message
    Oui, fuite de mémoire possible, mais dans mon cas impossible vu que je gère que mes textes ne fassent pas plus de 255 caractères, donc sa passe pile.
    Il ne s'agit pas d'une fuite de mémoire mais d'une perte de données, ce qui est différent. Et la longueur de tes textes n'est pas le problème. Le problème, c'est qu'un caractère d'une chaîne de type string peut contenir plus de choses qu'un caractère d'une chaîne de type shortstring.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 631
    Points : 10 558
    Points
    10 558
    Par défaut
    Le premier truc le plus embêtant, c'est que l'UTF-16 n'est pas compatible ASCII

    Une chaîne ASCII comme "Bonjour" va donner en UTF-16 "B\0o\0n\0j\0o\0u\0r\0" (<- en gros)

    Donc tu vois bien que
    • Si tu mets de l'UTF-16 dans une chaîne ASCII, tu n'auras [en apparence] que la première lettre
    • Si tu mets de l'ASCII dans une chaîne UTF-16, tu auras n'importe quoi "Bo" + "nj" + "ou" + "r\0"



    Édit: Dans l'exemple ci-dessous de Roland Chastain avec de l'ASCII cela fonctionne parce qu'il doit y avoir une moulinette dans l'opérateur d'affectation et/ ou les constructeurs [en fonction des types] pour ajouter/ supprimer les '\0' nécessaires pour avoir 1 octet dans 2 octets

    Édit: Comme l'a indiqué Andnotor, si on renseigne le code page, alors la conversion a de grande chance d'être sans perte puisque les moulinettes ont tous les renseignements.

  9. #9
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    J'ai essayé de faire un petit exemple qui mette en évidence le problème.

    L'idée est de transtyper une chaîne de type string en une chaîne de type shortstring, puis de faire un transtypage en sens inverse pour voir si des données ont été perdues en cours de route. Avec une lettre de l'alphabet latin, on constate qu'aucune donnée n'est perdue : à la limite on pourrait ignorer l'avertissement. En revanche, avec une lettre de l'alphabet grec, les données sont bel et bien perdues. Le caractère grec ne "rentre" pas dans la chaîne de type shortstring.

    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
    program DataLoss;
     
    {$APPTYPE CONSOLE}
     
    var
      s: string;
      ss: shortstring;
     
    begin
      SetLength(s, 1);
     
      // Exemple de transtypage sans perte de données :
     
      s[1] := #$0041;          // LATIN CAPITAL LETTER A
      ss := s;                 // W1058
      WriteLn(string(ss) = s); // TRUE
     
      // Exemple de transtypage avec perte de données :
     
      s[1] := #$0391;          // GREEK CAPITAL LETTER ALPHA
      ss := s;                 // W1058
      WriteLn(string(ss) = s); // FALSE
     
      ReadLn;
    end.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  10. #10
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 696
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 696
    Points : 13 135
    Points
    13 135
    Par défaut
    Citation Envoyé par foetus Voir le message
    Le premier truc le plus embêtant, c'est que l'UTF-16 n'est pas compatible ASCII

    Une chaîne ASCII comme "Bonjour" va donner en UTF-16 "B\0o\0n\0j\0o\0u\0r\0" (<- en gros)

    Donc tu vois bien que
    • Si tu mets de l'UTF-16 dans une chaîne ASCII, tu n'auras [en apparence] que la première lettre
    • Si tu mets de l'ASCII dans une chaîne UTF-16, tu auras n'importe quoi "Bo" + "nj" + "ou" + "r\0"
    La conversion est implicite, le compilateur se débrouille très bien à ce niveau. Les problèmes surviennent lorsqu'un buffer est rempli manuellement ou qu'un mauvais type a été utilisé dès le départ (ex. définir un paramètre d'une procédure exportée d'une DLL en ansistring plutôt que widestring).

    Parlons également d'ANSI et non d'ASCII.

    Citation Envoyé par Roland Chastain Voir le message
    J'ai essayé de faire un petit exemple qui mette en évidence le problème.

    L'idée est de transtyper une chaîne de type string en une chaîne de type shortstring, puis de faire un transtypage en sens inverse pour voir si des données ont été perdues en cours de route. Avec une lettre de l'alphabet latin, on constate qu'aucune donnée n'est perdue : à la limite on pourrait ignorer l'avertissement. En revanche, avec une lettre de l'alphabet grec, les données sont bel et bien perdues. Le caractère grec ne "rentre" pas dans la chaîne de type shortstring.
    Simplement parce que le Code Page n'est pas bon, la partie étendue de la table ANSI (128 à 255) n'est pas correctement mappée
    Essaye ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    type
      GreekString = type AnsiString(1253);
     
    var
      s1 :string;
      s2 :GreekString;
     
    begin
      s1 := #$03A9;          //Omega
      s2 := s1;              //s2 contient bien Omega
     
      Label1.Caption := s2;  //Retour en UnicodeString
    end;

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

Discussions similaires

  1. afficher du texte
    Par Mau dans le forum OpenGL
    Réponses: 10
    Dernier message: 24/06/2003, 15h31
  2. taille du texte dans un viewport
    Par pitounette dans le forum OpenGL
    Réponses: 3
    Dernier message: 22/07/2002, 12h06
  3. combobox->text
    Par clovis dans le forum C++Builder
    Réponses: 18
    Dernier message: 21/06/2002, 15h43
  4. fichier binaire ou texte
    Par soussou dans le forum C++Builder
    Réponses: 4
    Dernier message: 14/06/2002, 13h39
  5. Réponses: 2
    Dernier message: 10/06/2002, 11h03

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