Aide - Recherche - Membres - Calendrier
Version complète : Lecture d'un entier dans un fichier pdb
Les Forums de PalmAttitude.org > GENERAL PalmOS > Développement sous PalmOS
naguttes
Bon,

Ca faisait longtemps que je n'avais pas posé de question bête, donc en voici une :

Jusqu'à présent dans les fichiers que j'avais créés (un seul anim_wink.gif ), j'avais mes entiers en début d'enregistrement et mes chaînes de caractères (longueur variable) en fin. Pour lire un enregistrement (dans une structure Record), je lisais les entiers d'abord avec les instructions :
CITATION
RecordH=DmQueryRecord(LivreDB, index);
Record=MemHandleLock(RecordH);
// get the integers
gRecord.Number=Record->Number;  

et les chaînes de caractères avec un pointeur que j'incrémentais de la longueur de la chaîne lue :
CITATION
Ptr=Record->Titre;
StrCopy(gRecord.Titre,Ptr);
Ptr+=StrLen(Ptr)+1;
StrCopy(gRecord.SousTitre,Ptr);


Mais ce coup ci, va savoir pourquoi j'ai intercalé des entiers entre les chaînes de caractères. Je n'ai pas de problème pour lire les chaines (j'ajoute au pointeur la longueur de l'entier+1), mais je ne sais comment lire l'entier (et l'affecter dans ma structure).

Merci de votre aide
Patrice
Pour un entier court (short) :
i = ((UInt16) * ((UInt8 *) ptr)) << 8 + (UInt16) (* ((UInt8 *) (ptr + 1)))

Pour un entier long (long) :
i = ((UInt32) * ((UInt8 *) ptr)) << 24 + ((UInt32) * ((UInt8 *) ptr + 1)) << 16 + ((UInt32) * ((UInt8 *) ptr + 2)) << 8 + (* ((UInt8 *) (ptr + 3)))

Pas moyen de faire un cast (ce qui serait éminement plus simple) car tu t'exposes à des problèmes d'alignement.
naguttes
Merci,

Comme je ne lis pas le C couramment, je ne comprends pas bien l'opération que tu fais (qui d'ailleurs ne semble pas marcher quand je fais un copier/coller). Si tu as le temps peux tu m'expliquer ce que ça fait.

Merci
MarieC
wo p..n icon_bla.gif l'orgie de pointers 8O
Patrice
La méthode consiste à prendre chaque octet de l'entier, le décaler en fonction de sa position et l'ajouter au résultat.

Pour le cas "short" : tu prends le premier octet, tu le décales de 8 bits (ou tu le multiplies par 256) puis tu ajoutes le deuxième octet (sans décalage).

Il manque peut-être (encore) 1 ou 2 niveaux de parentèses :
i = (((UInt16) (* ((UInt8 *) ptr))) << 8 ) + (UInt16) (* ((UInt8 *) (ptr + 1)))

Et quelques autres dans la version "long" (je ne suis pas vraiment réveillé ce matin) : autour des (ptr+1), (ptr+2)...
naguttes
Ok merci, avec cette explication, je vais sans doute pouvoir trouver l'erreur.
Payalba
Un petite lecture du Kernighan et Richie ? anim_wink.gif
olivier101
Je suggère une solution plus simple et à mon avis plus lisible:

CODE
// On déclare un Int32 qui va contenir le résultat

Int32 res;



// p est un pointeur vers res, mais casté en type "Int8 *" de sorte que

// lorsqu'on l'incrémente, il ne bouge que d'1 octet à la fois

Int8* p = (Int8 *) &res;



// Ensuite on recopie 4 octets de ptr vers p

// (on pourrait aussi utiliser MemCopy ou similaire...)

*p++ = *ptr++;

*p++ = *ptr++;

*p++ = *ptr++;

*p++ = *ptr++;


Les problèmes d'alignement sont résolus par le fait que res est déclaré en Int32 et donc aligné correctement.
naguttes
A part Int8 que j'ai transformé en UInt8, c'est du "C Palm", car j'ai une erreur à la compile sur *p++ = *ptr++;
CITATION
warning : dereferencing 'void *' pointer

suivie de
CITATION
void value not ignored as it ought to be
Patrice
Transforme ton ptr en un UInt8 * ou ajoute des casts sur les assignations.

La solution d'O101 est effectivement plus "élégante" anim_wink.gif (mais la mienne a l'avantage de pouvoir se "macrotiser" simplement)
olivier101
CITATION(naguttes)
A part Int8 que j'ai transformé en UInt8, c'est du "C Palm", car j'ai une erreur à la compile sur *p++ = *ptr++;  
CITATION
warning : dereferencing 'void *' pointer

suivie de
CITATION
void value not ignored as it ought to be

Quoi, ptr est un void* ??? :+: Pas bien ça ! Tu vas me le transformer en UInt8 * ! sleep.gif
naguttes
CITATION(Patrice)
Transforme ton ptr en un UInt8 * ou ajoute des casts sur les assignations.


Je ne comprends pas icon_cry.gif , ptr est défini comme un pointeur (MemPtr) et pointe sur le début de mon enregistrement, comment puis je le redéfinir en UInt8

CITATION
La solution d'O101 est effectivement plus "élégante" anim_wink.gif (mais la mienne a l'avantage de pouvoir se "macrotiser" simplement)

Ca veut dire quoi "macrotiser" (en faire une macro mais encore?)

De toute façon aucune des 2 solutions ne marche pour l'instant (mais ç'est surement de ma faute anim_wink.gif )
Patrice
MemPtr est simplement défini comme (void *)...

T'as qu'à faire des :
*p++ = *((UInt8 *) ptr++);
naguttes
Ca marche merci, mais j'aurai bien besoin d'organiser la deuxième session de programmation anim_wink.gif
Ceci est une version "bas débit" de notre forum. Pour voir la version complète avec plus d'information, la mise en page et les images, veuillez cliquer ici.
Invision Power Board © 2001-2008 Invision Power Services, Inc.