begin process at 2010 02 10 10:08:37
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Delphi

 > 

Divers

 > 

Aide et documentation

 > 

incohérences sur le resultat de la fonction length


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

incohérences sur le resultat de la fonction length

mardi 31 mars 2009 à 22:17:09 | incohérences sur le resultat de la fonction length

jlen100

Membre Club
bonjour,
je viens de découvrir une incohérence dans le résultat renvoyé par le fonction length()
si l'on prend un type:
  TEntete=
  record
     Nom:String[50];
     Color:char;
     Validite:boolean;
     dateValidite:Tdatetime;
     nul:string[2];
  end;
var Entete:TEntete;
si l'on fait la somme de toute les longueurs on obtient 64
si l'on fait length(Entete) on obtient 72
Etrange Non???
la différence vient de la variable dateValidite qui a une longueur de 8 octets mais est comptée pour 16 octets dans le calcul.
pour s'en convaincre si l'on fait:
  TEnteteBadge=
  record
  Nom:String[50];
  Color:char;
  Validite:boolean;
   nul:string[10];
  end;
la fonction length renvoie bien 64
ceci est assez gênant quand on emploie cette fonction pour extraire la variable d'un TMemoryStream.
Quelqu'un aurait-il une explication?

@jlen


mardi 31 mars 2009 à 22:45:24 | Re : incohérences sur le resultat de la fonction length

f0xi

Membre Club Administrateur CodeS-SourceS

Length => string et array
pour tout autres choses : SizeOf !

MemoryStream.Read(Entete, SizeOf(TEntete);





jeudi 2 avril 2009 à 08:15:50 | Re : incohérences sur le resultat de la fonction length

jlen100

Membre Club
excuse moi foxi mais le résultat  est aussi incohérent pour le sizeof !!
jeudi 2 avril 2009 à 10:48:31 | Re : incohérences sur le resultat de la fonction length

f0xi

Membre Club Administrateur CodeS-SourceS


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
  { 50 bytes :
    [50 chars]
  }
  TEnteteName = array[0..49] of char;
  pEnteteName = ^TEnteteName;

const
  EnteteNameSize = SizeOf(TEnteteName);

function StringToEnteteName(const S: string): TEnteteName;
var N, L: integer;
begin
  L := Length(S)-1;
  if L > 49 then
    L := 49;
  for N := 0 to 49 do
    if N <= L then
      result[N] := S[N+1]
    else
      result[N] := #0;
end;

function EnteteNameToString(const E: TEnteteName): String;
var N : integer;
    pR: PChar;
begin
  SetLength(result, 50);
  pR := PChar(result);
  for N := 0 to 49 do
  begin
    pR[N] := E[N];
  end;
end;

type
  { 6 bytes :
    [2 Year][2 Month][2 Day]
  }
  TEnteteDate = record
    Year, Month, Day: word;
  end;
  pEnteteDate = ^TEnteteDate;

const
  EnteteDateSize = SizeOf(TEnteteDate);

function TEnteteDateToDateTime(const eDate: TEnteteDate): TDateTime;
begin
  result := EncodeDate(eDate.Year, eDate.Month, eDate.Day);
end;

function DateTimeToEnteteDate(const aDate: TDateTime): TEnteteDate;
begin
  DecodeDate(aDate, Result.Year, Result.Month, Result.Day);
end;

type
  { 60 bytes :
    [50 Name chars]
    [1 color]
    [1 Validity]
    [2 DateValidity Year][2 DateValidity Month][2 DateValidity Day]
    [2 nul]
  }
  TEntete = record
    Name         : TEnteteName;
    Color        : byte;
    Validity     : boolean;
    DateValidity : TEnteteDate;
    Nul          : word;
  end;
  pEntete = ^TEntete;

const
  EnteteSize = SizeOf(TEntete);



procedure TForm1.FormCreate(Sender: TObject);
begin
  caption := format('%d // %d // %d',[EnteteSize, EnteteNameSize, EnteteDateSize]);
end;

end.




jeudi 2 avril 2009 à 11:14:57 | Re : incohérences sur le resultat de la fonction length

jlen100

Membre Club
foxi,
Il te manque 4 octets et TEnteteDate n'est pas compatible avec un TDateTime 
(il y a plus simple  pour récupérer l'entête 
Var EnteteSize:Integer;
 const EnteteSize:=SizeOf(TEntete.Name)+1+1+SizeOf(TEntete.DateValidity)+SizeOf(TEntete.Nul);
 MemoryStream.Read(Entete, EnteteSize);
on écrit et on lit bien les bonnes variables.
mais cela n'explique pas pourquoi DELPHI se plante dans la conversion du DateValidity. lorsque il est dans un record
chez moi 51+1+1+8+3= 64 pas 72!
jeudi 2 avril 2009 à 11:31:37 | Re : incohérences sur le resultat de la fonction length

f0xi

Membre Club Administrateur CodeS-SourceS

y'a en fait 3 probleme sur ta premiere entete :

String[N] est toujours egal a N+1 (1 pour la taille de la chaine)

soit String[50] + String[2] = 51+3 = 54

ensuite pour TDateTime autre soucis, est censé etre Float 64bits (8 octets) mais se trouve stocké sur 16 octets!
soit un float 128bits !
incomprehensible. d'ou viennent les 8 octets suplementaire ?!

donc si on reprend :

  TEntete=
  record
     Nom:String[50];
     Color:char;
     Validite:boolean;
     dateValidite:Tdatetime;
     nul:string[2];
  end;

50 + 1 + 1 + 8 + 2 = 62 dans la theorie

51 + 1 + 1 + 16 + 3 = 72 dans la pratique 

SizeOf ne renvois donc pas une valeur erronée...


Mon type TEnteteDate est parfaitement compatible avec un TDateTime, mais pour cela il faut utiliser les methodes EncodeDate et DecodeDate pour la lire ... un moyen un peu contraignant de contourner le probleme de taille de TDateTime.
on pourrai pousser plus loin en declarant :

TEnteteDate = record
  Y, M, D, H, N, S, Z : word;
end;

mais cette fois, notre type ferait 14 octets et devras s'utiliser avec les methodes EncodeDateTime et DecodeDateTime.



jeudi 2 avril 2009 à 14:04:37 | Re : incohérences sur le resultat de la fonction length

Guillemouze

Réponse acceptée !
le probleme doit etre du a l'alignement des données. Si tu utilise un "packed record", le resultat devrait etre correcte
jeudi 2 avril 2009 à 14:31:16 | Re : incohérences sur le resultat de la fonction length

jlen100

Membre Club
merci foxi , merci guillemouze.

effectivement cela fonctionne avec packed record

Cela n'était pas un véritable problème de fonctionnement puisque j'avais trouvé une solution à "l'arrache" mais cela me turlupinait et je n'aime pas ne pas comprendre le pourquoi de la chose.
en fait la variable NUL n'est là que pour ajuster la longueur les données qui suivent sont d'un autre type qui lui fait 64 octets. J'aurais pu effectivement mettre la longueur à 61 ou 72 mais l'ajustement me simplifie les calculs de déplacement dans le stream.... on est toujours un peu flemmard des neurones et du clavier.

enfin encore merci à tous les deux.

Jlen.


Cette discussion est classée dans : fonction, string, resultat, length, incohérences


Répondre à ce message

Sujets en rapport avec ce message

limitation de sendtext ? [ par Xavier ] Bonjour,Comme la fonction sendtext prend en parametre un string et sachant qu'un string peut faire 2 Mo, pensez-vous qu'il est raisonnable d'utiliser Type d'une fonction d'une DLL [ par sebastienbro ] Voilà, j'aimerais savoir s'il est possible de retourner une auytre valeur que ShortString (String par exemple)Et si oui, comment, parceque dès que je Fonction qui retourne un array of string [ par arthur07 ] DR@G Bonjour, J'aurais besoin d'aide pour une fonction qui doit retourné un tableau. function Query(Query : string) : arr String pour appeler variable simple [ par lebdenat ] <TD id=HB_Focus_Element vAlign=top width="100%" background="" height=250 UNSELECTAB Caster un string en fonction [ par csweety13 ] Bonjour, Pour faire court, j'ai une variable de type string et une procédure, par exemple : public procedure fonction1(); Var1 : string; ... Var1 := Problème de fonction déclarée dans Public [ par crostif ] Bonjour,j'ai eu une fonction à déclarer en publique pour y faire appel depuis d'autres formes (les uses sont correctement déclarée)lors de la compilat probleme avec la fonction length [ par informatixo ] J'ai réalisé une fonction EstNumerique en m'inspirant d'une solution que delphiprog avait donné dans un post, donc ne vous étonnez pas de ce nom. Je Fonction pour convertir un extended en string? [ par stigmate101 ] Salut, j'ai une question très simple, je voudrais conertir un type extended en un type string. Merci d'avance @+ problème de sous répertoires [ par aforpien ] Bonjour à tous,Je travail en ce moment sur la réalisation d'un prog permettant le transfert automatique, via le protocol ftp, d'une arborescence de ré Conversion Float -> string , string -> float [ par dederfred ] Bonjour ,J'ai   chercher comment convertir un float en string et inversement mais je ne trouve pas la fonction...J'ai trouver en C (grace a google) co


Nos sponsors


Sondage...

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,733 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales