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 :

Taille d'un tableau dynamique


Sujet :

Langage Delphi

  1. #1
    Rédacteur
    Avatar de omen999
    Profil pro
    Inscrit en
    Février 2006
    Messages
    1 297
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 1 297
    Points : 3 551
    Points
    3 551
    Par défaut Taille d'un tableau dynamique
    bonjour,

    je reviens sur un vieux code delphi ANSI standard (<=D7) et je
    suis un peu perplexe sur la taille du tableau dynamique que me renvoie le prog
    je lis dans un TFileStream une chaine unicode avec un size header de 4 octets sans zéro terminal
    après redimensionnement de mon tableau j'y stocke le contenu en y ajoutant le zéro terminal
    et pour finir je convertis ce tableau en une chaine ANSI dont le contenu et la taille correspond au résultat attendu
    l'affichage test de la chaine unicode est également correct
    en revanche si je cherche à connaître sa taille le résultat est complètement fantaisiste (taille réelle : 62 taille affichée : x13BA7401)
    pourtant je pensais que Length donnait bien le nb d'éléments du tableau. pour info High() donne Length()+1...
    le code abrégé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    wKeyWords:array of WideChar;
    sKeyWords:string;
    aDataSize:array[0..3] of Byte;
    iLength:LongInt;
     
    iLength:=oPFileStream.Read(aDataSize,4);
    SetLength(wKeyWords,Integer(aDataSize)*2 + 2); //+ zéro terminal
    FillChar(wKeyWords[0],Integer(aDataSize)*2 + 2,0); <- erreur rectifiée
    iLength:=oPFileStream.Read(wKeyWords,Integer(aDataSize)*2);
    messagebox (0,pchar(inttostr(Length(wKeyWords))),pchar(inttostr(High(wKeyWords))), 0);  // la taille est incohérente !
    messageboxw (0, @wKeyWords, 'la chaine unicode', 0); // affichage correct
    edit : mauvaise transcription du code rectifiée
    nomen omen, nemo non omen - Consultez la FAQ VBScript et les cours et tutoriels VBScript
    le plus terrible lorsqu'une voiture renverse un piéton, c'est que ce sont les freins qui hurlent. (ramón)
    pas de questions techniques par mp

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 745
    Points : 13 306
    Points
    13 306
    Par défaut
    As-tu contrôlé ce que valait Integer(aDataSize) ?

  3. #3
    Rédacteur
    Avatar de omen999
    Profil pro
    Inscrit en
    Février 2006
    Messages
    1 297
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 1 297
    Points : 3 551
    Points
    3 551
    Par défaut
    oui, la valeur est exacte (les données sont bien en little endian et correctement transtypées)
    en fait c'est la méthode Read qui perturbe le format de mon tableau
    nomen omen, nemo non omen - Consultez la FAQ VBScript et les cours et tutoriels VBScript
    le plus terrible lorsqu'une voiture renverse un piéton, c'est que ce sont les freins qui hurlent. (ramón)
    pas de questions techniques par mp

  4. #4
    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
    1) pourquoi déclarer "aDataSize:array[0..3] of Byte;" et non "aDataSize: Integer" ?

    2) oPFileStream.Read(wKeyWords[0],Integer(aDataSize)*2);
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  5. #5
    Rédacteur
    Avatar de omen999
    Profil pro
    Inscrit en
    Février 2006
    Messages
    1 297
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 1 297
    Points : 3 551
    Points
    3 551
    Par défaut
    1) pourquoi déclarer "aDataSize:array[0..3] of Byte;" et non "aDataSize: Integer" ?
    par habitude... pour accéder au besoin aux octets directement j'aime les transtypage inutiles
    mais cette modif ne change rien
    2) oPFileStream.Read(wKeyWords[0],Integer(aDataSize)*2);
    erreur de transcription déjà modifiée dans mon message initial

    pour info, le strict remplacement du tableau dynamique par un tableau fixe de WideChar renvoie en revanche une taille parfaitement correcte
    une idée ?

    edit : pour ta remarque n°2 j'ai confondu la ligne...
    pointer sur le premier item du tableau pour la lecture du TFileStream renvoie bien la bonne taille...mais pas un tableau cohérent ce qui n'est pas
    illogique puisque rien ne garanti que les items soient contigus en mémoire
    nomen omen, nemo non omen - Consultez la FAQ VBScript et les cours et tutoriels VBScript
    le plus terrible lorsqu'une voiture renverse un piéton, c'est que ce sont les freins qui hurlent. (ramón)
    pas de questions techniques par mp

  6. #6
    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
    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
     
    var
      wKeyWords:array of WideChar;
    //  sKeyWords:string; // non utilisé
     
      aDataSize:array[0..3] of Byte; // Integer
      iLength:LongInt;
    begin
      iLength:=oPFileStream.Read(aDataSize,4);
      // SetLength(wKeyWords,Integer(aDataSize)*2 + 2); //+ zéro terminal
      SetLength(wKeyWords,Integer(aDataSize) + 1); // wKeywords est un tableau de WideChar qui occupent déjà 2 octets
     
    //  FillChar(wKeyWords[0],Integer(aDataSize)*2 + 2,0); <- erreur rectifiée
      FillChar(wKeyWords[0],Integer(aDataSize) + 1 ,0); <- erreur rectifiée
     
    //  iLength:=oPFileStream.Read(wKeyWords,Integer(aDataSize)*2);
      iLength:=oPFileStream.Read(wKeyWords[0],Integer(aDataSize)*2); 
     
    //  messagebox (0,pchar(inttostr(Length(wKeyWords))),pchar(inttostr(High(wKeyWords))), 0);  // la taille est incohérente !
      ShowMessage(IntToStr(Length(wKeywords)); // c'est très exactement Integer(aDataSize) + 1
     
    //  messageboxw (0, @wKeyWords, 'la chaine unicode', 0); // affichage correct
    // je suis très surpris !
      messageboxw (0, PChar(wKeyWords), 'la chaine unicode', 0);
    maintenant il serait tout aussi simple de travailler comme cedi

    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
      sKeyWords:string;   
      aDataSize: Integer;
    begin
      oPFileStream.Read(aDataSize,4);
     
      SetLength(sKeyWords, aDataSize); 
     
      oPFileStream.Read(wKeyWords[1], aDataSize * SizeOf(Char)); 
     
      ShowMessage(IntToStr(Length(sKeywords)); 
     
      ShowMessage(sKeyWords);
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 745
    Points : 13 306
    Points
    13 306
    Par défaut
    FillChar remplit un certain nombre d'octets, c'est bien DataSize *2 pour une widestring.

  8. #8
    Rédacteur
    Avatar de omen999
    Profil pro
    Inscrit en
    Février 2006
    Messages
    1 297
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 1 297
    Points : 3 551
    Points
    3 551
    Par défaut
    c'est bien DataSize *2 pour une widestring.
    je confirme

    @Paul
    ton 2eme code oublie que je dois traiter une chaine unicode sans zéro terminal
    c'est manifestement un problème de gestion foireuse du header size du tableau dynamique dans cette vieille version
    j'ai laissé tombé la variable (mal) "managée" pour taper dans le tas à l'ancienne
    le code qui fonctionne nickel :
    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
    var
     sKeyWords:string;
     aDataSize:array[0..3] of Byte;
     PWC:PWideChar;
     iDataSize:LongInt;
     iLength:LongInt;
    begin
    ...
    iLength:=oPFileStream.Read(aDataSize,4);
    iDataSize:=Integer(aDataSize)*2;
    PWC:=AllocMem(iDataSize+2);// ne pas oublier la place pour le zéro terminal...
    //GetMem(PWC,iDataSize+2); ---EDIT
    iLength:=oPFileStream.Read(PWC^,iDataSize);
    messagebox (0,pchar(inttostr(Length(PWC))),pchar(inttostr(iLength)), 0); //parfait
    messageboxw (0, PWC,'', 0); //la chaine unicode
    merci pour votre aide et à bientôt

    edit:petite modif du code
    nomen omen, nemo non omen - Consultez la FAQ VBScript et les cours et tutoriels VBScript
    le plus terrible lorsqu'une voiture renverse un piéton, c'est que ce sont les freins qui hurlent. (ramón)
    pas de questions techniques par mp

  9. #9
    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
    Citation Envoyé par Andnotor Voir le message
    FillChar remplit un certain nombre d'octets, c'est bien DataSize *2 pour une widestring.
    en effet, mais vu que derrière on fait un Read() de la même longueur, cette ligne ne sert strictement à rien au pire c'est uniquement le dernier caractère qu'il faut mettre à 0

    et dans mon second code, comme indiqué dans le commentaire, les strings possèdent automatiquement un 0 terminal invisible, il est inutile de l'ajouter
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 745
    Points : 13 306
    Points
    13 306
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    cette ligne ne sert strictement à rien au pire c'est uniquement le dernier caractère qu'il faut mettre à 0
    On est parfaitement d'accord

    Mais là, s'il n'y a pas cette multiplication, les dernier caractère ne le sera pas ; à 0.

    Aprés, omen999 parle de "<= Delphi 7". Quelle est le compilateur actuel ? Plutôt String ou WideString ? Char ou WideChar ?

    WideString/WideChar auraient l'avantage de fonctionner avec toutes les versions.

  11. #11
    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
    Citation Envoyé par Andnotor Voir le message
    On est parfaitement d'accord

    Mais là, s'il n'y a pas cette multiplication, les dernier caractère ne le sera pas ; à 0.

    Aprés, omen999 parle de "<= Delphi 7". Quelle est le compilateur actuel ? Plutôt String ou WideString ? Char ou WideChar ?

    WideString/WideChar auraient l'avantage de fonctionner avec toutes les versions.
    au temps pour moi, j'avais mal interprété l'info, je pensais que c'était un vieux code D7 réutilisé sous un Delphi récent...mais en effet rien ne l'indique

    ceci dit on a en effet les WideString sous D<=7

    ça devrait donner ceci du coup

    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
     
    var
      aDataSize: Integer;
      wKeyWords: WideString;   
      sKeyWords: string;
    begin
      oPFileStream.Read(aDataSize,4);
     
      SetLength(wKeyWords, aDataSize); 
     
      oPFileStream.Read(wKeyWords[1], aDataSize * SizeOf(WideChar)); 
     
      sKeyWords := wKeyWords; // conversion ANSI
     
      ShowMessage(IntToStr(Length(sKeywords)); 
     
      ShowMessage(sKeyWords);
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  12. #12
    Rédacteur
    Avatar de omen999
    Profil pro
    Inscrit en
    Février 2006
    Messages
    1 297
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 1 297
    Points : 3 551
    Points
    3 551
    Par défaut
    C'est même du D4 compilé sur D4 (je convertirai en 10.2 +tard )
    sinon le dernier code est parfait
    j'aurais appris que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    aData:array of WideChar;
    SetLength(aData,63);
    n'est pas équivalent (au typage près) à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    aData:WideString;
    SetLength(aData,62);
    merci pour tous ces exemples
    nomen omen, nemo non omen - Consultez la FAQ VBScript et les cours et tutoriels VBScript
    le plus terrible lorsqu'une voiture renverse un piéton, c'est que ce sont les freins qui hurlent. (ramón)
    pas de questions techniques par mp

Discussions similaires

  1. Réponses: 7
    Dernier message: 10/01/2007, 15h07
  2. Changer la taille d'un tableau dynamique
    Par clem1313 dans le forum Langage
    Réponses: 1
    Dernier message: 28/02/2006, 01h57
  3. Réponses: 6
    Dernier message: 16/01/2006, 13h29
  4. Comment récupérer la taille d'un tableau dynamique ?
    Par Tchaill39 dans le forum Langage
    Réponses: 4
    Dernier message: 08/12/2005, 14h21
  5. Connaitre la taille d'un tableau dynamique
    Par lewellah dans le forum C
    Réponses: 2
    Dernier message: 23/09/2005, 18h37

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