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

Free Pascal Discussion :

Différence entre écrire une chaîne et écrire un caractère dans la console


Sujet :

Free Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur/Modérateur

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

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 173
    Billets dans le blog
    9
    Par défaut Différence entre écrire une chaîne et écrire un caractère dans la console
    Bonjour ! Je suis en train d'étudier les questions d'encodage et je m'intéresse à titre d'exemple au problème des accents dans la console Windows.

    Je ne m'explique pas le résultat du programme suivant. Pourquoi le résultat n'est-il pas deux fois le même ? À quel moment la différence se fait-elle ?

    Si je remplace 133 par 233, c'est le premier caractère qui est correct.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var
      s: string;
     
    begin
      SetLength(s, 1);
      s[1] := #130;
      WriteLn(s);
      WriteLn(s[1]);
    end.
     
    {
      '
      é
    }

  2. #2
    Rédacteur/Modérateur

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

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 173
    Billets dans le blog
    9
    Par défaut
    Bref, si j'écris une chaîne de caractères dans la console, je dois utiliser la table ANSI ; si j'écris un caractère, la table OEM.

    Question subsidiaire. En supposant que l'usage normal soit d'écrire une chaîne, il faut donc encoder en ANSI pour écrire dans la console, et non pas en OEM ? Pourtant si je veux écrire depuis un batch avec des caractères accentués correctement restitués, je dois encoder le batch en OEM. Je n'y comprends plus rien.

  3. #3
    Membre émérite

    Homme Profil pro
    Rédacteur technique (retraité)
    Inscrit en
    Octobre 2009
    Messages
    168
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 82
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Rédacteur technique (retraité)

    Informations forums :
    Inscription : Octobre 2009
    Messages : 168
    Par défaut
    Bonjour, et Bonne Année (avec 24h d'avance) !

    La différence est que s renvoie une valeur de type ansistring (sujet à des conversions codepage) alors que s[1] renvoie un type char (jamais de conversion).

    Il est intéressant d'essayer ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    uses sysutils, Windows;
    var
      s: string;
     
    begin
      SetLength(s, 1);
      s[1] := #130;
      WriteLn('CP=', intToStr(stringcodepage(s)));  // affiche 1252 (page de code ANSI)
      SetCodePage(rawbytestring(s), GetOemCP, false); // change l'ID page de code de s sans modifier la chaîne elle-même
      WriteLn('CP=', intToStr(stringcodepage(s)));  // affiche 850 (page de code OEM)
      WriteLn(s);   
      WriteLn(s[1]); 
    end.
    Je présume qu'une conversion intervient lors du passage d'un paramètre ansistring à WriteLn si WriteLn est associé à la console et que la chaîne n'est pas OEM.
    Cette conversion n'intervient pas pour un type char.

  4. #4
    Rédacteur/Modérateur

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

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 173
    Billets dans le blog
    9
    Par défaut
    @DomDA91

    Merci, je crois que j'ai compris. Dans la foulée, j'ai relu avec profit cette discussion, que j'avais un peu oubliée.

    Moralité, il ne suffit pas de mettre les bonnes valeurs dans le corps de la chaîne, il faut aussi mettre à jour la "carte d'identité" de la chaîne. Si on ne le fait pas, le compilateur reconvertit la chaîne, d'où les erreurs. J'ai bon ?

    J'attends un peu avant de clore la discussion. Bonne année à vous aussi ! Mais c'est vrai que nous n'y sommes pas encore.

  5. #5
    Rédacteur/Modérateur

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

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 173
    Billets dans le blog
    9
    Par défaut
    C'est aujourd'hui que j'ai compris ce que fait la procédure SetCodePage. J'avais toujours plus ou moins cru qu'elle faisait une conversion du contenu de la chaîne. Merci de m'avoir éclairé.

    Pour conclure (provisoirement) l'histoire du "é" dans la console Windows, un petit programme basé sur un exemple de Paul TOTH et sur l'explication de DomDA91.

    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    uses
      SysUtils;
     
    { https://www.developpez.net/forums/d1732510/environnements-developpement/delphi/contribuez/ne-prenez-pieds-strings/#post9515065 }
     
    type
      TStringInfo = record
        CodePage: Word;
        CharSize: Word;
        RefCount: Integer;
        Length  : Integer;
      end;
     
    procedure StringInfo(p: Pointer);
    var
      i: ^TStringInfo;
    begin
      i := p; // l'adresse du premier caractère
      Dec(i); // remonter de SizeOf(TStringInfo) en mémoire
      WriteLn(' CodePage = ', i^.CodePage);
      WriteLn(' CharSize = ', i^.CharSize);
      WriteLn(' RefCount = ', i^.RefCount);
      WriteLn(' Length   = ', i^.Length);
    end;
     
    var
      s: string;
     
    begin
      s := 'é';
      WriteLn(Length(s) = 1); // FALSE
      StringInfo(pointer(s));
      WriteLn(s);
     
      SetCodePage(rawbytestring(s), 850, FALSE); // 850 ou GetOemCP de l'unité Windows
      StringInfo(pointer(s));
      WriteLn(s);
     
      SetLength(s, 1);
      s[1] := #130;
      StringInfo(pointer(s));
      WriteLn(s);
    end.
    Code X : 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
      C:\Atelier\Pascal\encoding>stringinfotest
      FALSE
       CodePage = 0
       CharSize = 1
       RefCount = -1
       Length   = 2
      é
       CodePage = 850
       CharSize = 1
       RefCount = 1
       Length   = 2
      ├®
       CodePage = 850
       CharSize = 1
       RefCount = 1
       Length   = 1
      é
    
      C:\Atelier\Pascal\encoding>

  6. #6
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 971
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 971
    Par défaut
    Bonjour,

    Eh oui, et ce problème va encore nous les briser longtemps, jusqu'à ce que TOUS les systèmes soient en Unicode.

Discussions similaires

  1. Réponses: 5
    Dernier message: 16/10/2015, 13h31
  2. Réponses: 3
    Dernier message: 18/11/2011, 19h23
  3. Écrire une chaîne de caractères
    Par chester89 dans le forum x86 16-bits
    Réponses: 1
    Dernier message: 18/11/2010, 00h54
  4. Réponses: 5
    Dernier message: 30/09/2008, 13h36
  5. différence entre exporter une base de données ou la détacher
    Par boumbo73 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 12/03/2008, 11h54

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