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 :

Types Incompatibles AnsiChar et Char !


Sujet :

Delphi

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2018
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : Autriche

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2018
    Messages : 23
    Points : 11
    Points
    11
    Par défaut Types Incompatibles AnsiChar et Char !
    Salut tout le monde ! j'ai un petit problème qui me bloque ; j'utilise XE5 , pourquoi j'ai ce message d'erreur en compilant le programme ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure TForm1.SpeedButton1Click(Sender: TObject);
    var
     s: string[255];
     c: array[0..255] of Byte absolute s;
     i: Integer;
    begin
     s := Edit1.Text;
     for i := 1 to ord(s[0]) do c[i] := 10 xor c[i];
     Memo1.Text:=s;
     for i:=1 to Length(s) do s[i] := Char(10 xor ord(s[i]));
      Memo2.Text:=s;
    end;
    merci de répondre a ma question

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 042
    Points : 40 955
    Points
    40 955
    Billets dans le blog
    62
    Par défaut
    Bonjour,
    Réponse rapide : parce que vous êtes confronté à de l'Unicode.
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  3. #3
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 858
    Points : 11 301
    Points
    11 301
    Billets dans le blog
    6
    Par défaut
    Bonjour,
    Il est certain que mentionner l'endroit du code qui déclenche l'erreur est un plus...
    s[i] := Char(10 xor ord(s[i])); // ici, peut-être ?
    je pense que la chaîne s est une AnsiString (caractères sur un octet), mais que le type Char est en Unicode (caractères sur deux octets).
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  4. #4
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2018
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : Autriche

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2018
    Messages : 23
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par tourlourou Voir le message
    Bonjour,
    Il est certain que mentionner l'endroit du code qui déclenche l'erreur est un plus...
    s[i] := Char(10 xor ord(s[i])); // ici, peut-être ?
    je pense que la chaîne s est une AnsiString (caractères sur un octet), mais que le type Char est en Unicode (caractères sur deux octets).
    Oui vous avez raison le message d'erreur indique cette ligne
    for i:=1 to Length(s) do s[i] := Char(10 xor ord(s[i]));
    mais je ne comprends pas ; tout semble correct comment faire alors?!

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    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 459
    Points : 24 873
    Points
    24 873
    Par défaut
    C'est ce que l'on appele une ShortString, c'est une Chaine Ansi
    Différent du string sans longueur, le type naturel en Delphi, qui est une Chaine Unicode (depuis une dizaine d'année)

    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
    procedure TForm1.SpeedButton1Click(Sender: TObject);
    var
      s: string[255]; // avec longueur, type ShortString avec AnsiChar
      c: array[0..255] of Byte absolute s;
      i: Integer;
    begin
      s := Edit1.Text; // Ici Problablement un warning de conversion implicite avec perte, cela doit être pris au sérieux et toujours faire en sorte que coder autrement
      for i := 1 to ord(s[0]) do
        c[i] := 10 xor c[i];
      Memo2.Lines.Add(s); // Add sera plus intéressant pour voir les résultats se cumuler
     
      for i:=1 to Length(s) do 
        s[i] := AnsiChar(10 xor ord(s[i])); // Faut juste utiliser le bon type, la réponse était dans le message d'erreur
      Memo2.Lines.Add(s);
    end;
    Attention, absolute c'est rigolo, disons que pour éviter quelques Cast as Class, cela peut rendre le code plus lisible
    Pour l'accès mémoire de type complexe comme les tableaux, c'est une prise de risque notable

    Eviter ShortString, string[...] ou AnsiString la plupart du temps, n'utilisez QUE string
    Votre code sera adapté à l'utilisation de la VCL
    Les autres types seront utile quand vous attaquerez des API plus pointues


    Etudiez le code suivant qui joue avec la différence entre le AnsiChar 8Bits et le WideChar 16Bits

    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
    var
      s: string; // sans longueur, type UnicodeString avec WideChar synonyme de Char en DXE5
      i: Integer;
    begin
      // La différence commencera à se voir si vous sortez du Latin1 classique comme Œ ou œ qui appartiennent à la seconde page Unicode
      s := Edit1.Text + '"Œ" ou "œ"';
      for i := 1 to Length(S) do
        s[i] := Char(10 xor Ord(s[i])); // Cette fois c'est Ord et Char, Ord ne renvoi pas un Byte comme le dit la Doc mais bien un Word, registe ASM 16Bits utilisé CX pour un XOR CX
      Memo2.Lines.Add(s);
     
      for i:=1 to Length(s) do
        s[i] := Char(10 xor Ord(s[i]));
      Memo2.Lines.Add(s);
     
      s := Edit1.Text + '"Œ" ou "œ"';
      for i := 1 to Length(S) do
        s[i] := Char(10 xor Word(s[i])); // Cette fois c'est Word et Char, toujours en XOR CX opération ASM 16Bits
      Memo2.Lines.Add(s);
     
      for i:=1 to Length(s) do
        s[i] := Char(10 xor Word(s[i]));
      Memo2.Lines.Add(s);
     
      s := Edit1.Text + '"Œ" ou "œ"';
      for i := 1 to Length(S) do
        s[i] := Char(10 xor Byte(s[i])); // C'est un Byte explicite, le registre sera réduit à CL, donc un 8Bit XOR CL
      Memo2.Lines.Add(s);
     
      for i:=1 to Length(s) do
        s[i] := Char(10 xor Byte(s[i])); // Et ici on constate la perte du passage en Byte (AnsiChar) au lieu de manipuler un Char
      Memo2.Lines.Add(s);
    end;
    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

  6. #6
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 496
    Points : 2 762
    Points
    2 762
    Billets dans le blog
    10
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    var
     s1 : AnsiSTring ;
     i: Integer;
    begin
     s1 := Edit1.Text;
     for i := 1 to length (s1) do s1[i] := ansiChar(10 xor byte(s1[i]));
     Memo1.Text:=s1;
     ....
    end;

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2018
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : Autriche

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mai 2018
    Messages : 23
    Points : 11
    Points
    11
    Par défaut
    Merci ! vous êtes super gentil ! merci aussi a ALWEBER,tourlourou,SergioMaster

  8. #8
    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 445
    Points
    28 445
    Par défaut
    tant qu'à fait des choses crades

    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
     
    procedure TMain.Edit1Change(Sender: TObject);
    {$POINTERMATH ON}
    var
      s: string;
      w: PWord;
      i: Integer;
    begin
      s := Edit1.Text;
      w := Pointer(s);
      Dec(w); // car 0 basé
      for i := 1 to Length(s) do
        w[i] := 10 xor w[i];
      Edit2.Text := s;
    end;
    mais attention, les string Unicode ne sont pas neutres...jusque Delphi 2009 le type String était un blob binaire dans lequel on pouvait faire ce qu'on voulait, mais depuis l'unicode, les caractères ont un sens, et notamment si on fait passer la chaîne transformée dans une chaîne Ansi (pour la stocker dans un fichier INI Ansi par exemple) puis qu'on la remet dans un String Unicode, il y a des chances qu'elle ne soit pas correctement décodée par la suite. Car il n'y a pas forcément une conversion sans perte de l'Unicode avec des caractères 16bits vers de l'Ansi...on a même un Warning à ce sujet
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

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

Discussions similaires

  1. "Types incompatibles" : char* et char[5000]
    Par Invité dans le forum Débuter
    Réponses: 4
    Dernier message: 26/09/2011, 21h55
  2. [VB.NET] Type Incompatible
    Par Cyrilange dans le forum Windows Forms
    Réponses: 6
    Dernier message: 08/11/2009, 20h08
  3. ODBC Access => Type Incompatible avec un champ DATE ?
    Par MaTHieU_ dans le forum C++Builder
    Réponses: 6
    Dernier message: 23/04/2005, 02h02
  4. Types Incompatibles
    Par olivierlsf dans le forum Bases de données
    Réponses: 1
    Dernier message: 11/03/2005, 18h01
  5. [LG]Problême "types incompatibles"
    Par pierrOPSG dans le forum Langage
    Réponses: 7
    Dernier message: 23/04/2004, 21h34

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