Question sur la taille des variables et problème sur les strings

Résolu
cs_Squallou Messages postés 249 Date d'inscription mardi 5 août 2003 Statut Membre Dernière intervention 15 juillet 2006 - 2 juil. 2006 à 13:55
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 - 3 juil. 2006 à 12:40
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

ThWilliam Messages postés 418 Date d'inscription mardi 3 janvier 2006 Statut Membre Dernière intervention 26 novembre 2013 4
2 juil. 2006 à 19:06
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 
3
florenth Messages postés 1023 Date d'inscription dimanche 1 août 2004 Statut Membre Dernière intervention 17 août 2008 3
2 juil. 2006 à 19:44
3
ThWilliam Messages postés 418 Date d'inscription mardi 3 janvier 2006 Statut Membre Dernière intervention 26 novembre 2013 4
2 juil. 2006 à 14:20
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
0
cs_Squallou Messages postés 249 Date d'inscription mardi 5 août 2003 Statut Membre Dernière intervention 15 juillet 2006
2 juil. 2006 à 14:25
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...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_Squallou Messages postés 249 Date d'inscription mardi 5 août 2003 Statut Membre Dernière intervention 15 juillet 2006
2 juil. 2006 à 19:19
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 ? :/
0
ThWilliam Messages postés 418 Date d'inscription mardi 3 janvier 2006 Statut Membre Dernière intervention 26 novembre 2013 4
2 juil. 2006 à 19:48
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
0
ThWilliam Messages postés 418 Date d'inscription mardi 3 janvier 2006 Statut Membre Dernière intervention 26 novembre 2013 4
2 juil. 2006 à 19:50
Salut Florent,

Te voilà de retour ? Cela fait plaisir.

Thierry
0
cs_Squallou Messages postés 249 Date d'inscription mardi 5 août 2003 Statut Membre Dernière intervention 15 juillet 2006
2 juil. 2006 à 20:28
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 ?
0
cs_Squallou Messages postés 249 Date d'inscription mardi 5 août 2003 Statut Membre Dernière intervention 15 juillet 2006
3 juil. 2006 à 11:24
Merci pour ton aide en privé florenth ^^
0
Emandhal Messages postés 194 Date d'inscription dimanche 2 mars 2003 Statut Membre Dernière intervention 10 octobre 2006 3
3 juil. 2006 à 12:22
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...
0
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
3 juil. 2006 à 12:40
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'
0
Rejoignez-nous