Question sur la taille des variables et problème sur les strings [Résolu]

Signaler
Messages postés
249
Date d'inscription
mardi 5 août 2003
Statut
Membre
Dernière intervention
15 juillet 2006
-
Messages postés
1725
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
11 avril 2021
-
Hello tout le monde !

J'ai 2 petites questions (sans grand rapport mais bon je vais pas poster 2 messages pour ça...).

1) J'ai le problème suivant : j'ai défini un type simple qui est :

type TMonType = record
Nom: String[12];
Quantite: Cardinal;
end;

La taille de Nom est de 12 octets et celle de Quantité de 4 non ? Soit 16 au total. Alors pourquoi lorsque je fais SizeOf(TMonType) ça me met 20 ? Comprends pas... -_-

2) 2ème problème. Je lis un String de taille 12 (String[12]) dans un flux. Aucun problème jusque là. Par contre lorsque je veux l'afficher (dans le Caption de ma fenêtre par exemple) il me manque le 1er caractère ! Pourtant lorsque je fais MonString[0] il me l'affiche bien tout seul ! Là non plus je ne comprends pas...


Y'a-t-il quelqu'un pour me sauver de cette horrible incompréhension ? :)
Merci d'avance...

11 réponses

Messages postés
418
Date d'inscription
mardi 3 janvier 2006
Statut
Membre
Dernière intervention
26 novembre 2013
3
Bonjour Squallou,

Si Chaine[0] te renvoie le 1° caractère, c'est parce que tu as écrit dans le flux avec décalage d'un octet.

var
   S1, S2: string[12];
   TempStream : TMemoryStream;
begin
    S1:= 'BONJOUR';
    TempStream := TMemoryStream.Create;
    TempStream.WriteBuffer(S1[ 1 ], Sizeof(S1));  // décalage !!!
    TempStream.Position : = 0;  // on se remet au début
    TempStream.ReadBuffer(S2, Sizeof(S2));  // on lit la valeur et on l'assigne à S2
    TempStream.Free;
    Label1.Caption:= S2;  // résultat ONJOUR , pcq un label lit à partir de [1]
    Label2.Caption: = S2[0]; // résultat B
end;

Avec : TempStream.WriteBuffer(S1, Sizeof(S1))
    S[0] contient bien la longueur de la chaine et S[1] = B

Voilà, c'est la seule explication que j'ai trouvée.
A +
Thierry 
Messages postés
1023
Date d'inscription
dimanche 1 août 2004
Statut
Membre
Dernière intervention
17 août 2008
2
Messages postés
418
Date d'inscription
mardi 3 janvier 2006
Statut
Membre
Dernière intervention
26 novembre 2013
3
Bonjour Squallou,

Dans une variable chaine de type court, le premier octet stocke la longueur de la chaine.
Donc MonString[0] : contient la longueur de la chaine et non un caractère.
Le problème vient sans doute de la lecture dans le flux.
Un string[12] occupe en fait 13 octets.

A +
Thierry
Messages postés
249
Date d'inscription
mardi 5 août 2003
Statut
Membre
Dernière intervention
15 juillet 2006

Ha oui en effet je viens de voir ça dans ... l'aide de Delphi. J'ignorais totalement ça. Mais c'est tout de même marrant car par exemple si j'ai une chaine courte, Chaine[0] me renvoit bien le 1er caractère de ma chaine et pas la longueur... C'est peut-être fait exprès par Delphi...
Messages postés
249
Date d'inscription
mardi 5 août 2003
Statut
Membre
Dernière intervention
15 juillet 2006

Moi c'était simplement :

S1 := 'BONJOUR';
TempStream.Position := 0;
TempStream.Write(S1, SizeOf(S1));

TempStream.Position := 0;
TempStream.Read(S2, SizeOf(S2));
Form1.Caption := S2; //Caption m'affiche 'ONJOUR'...

Donc voilà. Mais si tu me dis qu'en effet un Label (ou Caption ça revient au même) lit à partir de Chaine[1], ok pour le décalage mais à ce moment là Chaine[0] contiendrait le 1er caractère et où serait passé le 1er octets qui contient la taille ? :/
Messages postés
418
Date d'inscription
mardi 3 janvier 2006
Statut
Membre
Dernière intervention
26 novembre 2013
3
Bon, là, je jette l'éponge...
Pcq avec ton code, chez moi : Form1.Caption m'affiche 'BONJOUR' !
Le décalage aurait pu survenir avant, mais comme tu écris ta chaine en position zéro...

Remarque à propos du décalage : le 1° caractère s'est mis en position 0, et donc il n'y a plus pour Delphi de taille ! Fais l'expérience avec un write de 2 chaines [7] dont la première est initialisée à 'BONJOUR' et la deuxième à 'FIN' et tu vas voir le résultat...

A +
Thierry
Messages postés
418
Date d'inscription
mardi 3 janvier 2006
Statut
Membre
Dernière intervention
26 novembre 2013
3
Salut Florent,

Te voilà de retour ? Cela fait plaisir.

Thierry
Messages postés
249
Date d'inscription
mardi 5 août 2003
Statut
Membre
Dernière intervention
15 juillet 2006

En effet c'est beaucoup plus clair grâce à ton tuto florenth :)
J'avais pas compris que S[1] renverrait aussi ce qu'il y a après lol donc forcément...

Sinon aucune idée pour mon :

type TMonType = record
Nom: String[12];
Quantite: Cardinal;
end;

qui me donne SizeOf(TMonType) égal à 20 ?
Messages postés
249
Date d'inscription
mardi 5 août 2003
Statut
Membre
Dernière intervention
15 juillet 2006

Merci pour ton aide en privé florenth ^^
Messages postés
194
Date d'inscription
dimanche 2 mars 2003
Statut
Membre
Dernière intervention
10 octobre 2006
2
C'est pas parce que String[12]=12 octets + 4 taille de Nom + 4 du Cardinal ?
Parce que là ca fait 20 ^^


Tout problème a sa solution... Mais en général, celle que l'on trouve n'est jamais la bonne...
Messages postés
1725
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
11 avril 2021
8
Salut,

Non non, Emandhal. String[12] ça fait bien 13 octets, et cardinal 4.
Il est intéressant de remplacer le record par un packed record : là on a bien le compte.
Il s'agirait d'un problème d'alignement à 32 bits, mais je n'ai pas le temps de chercher l'explication pour l'instant...

Bonne prog'