[C] Sprintf et transformation en octet
Fermé
boelraty
Messages postés
2
Date d'inscription
mercredi 30 juillet 2008
Statut
Membre
Dernière intervention
30 juillet 2008
-
30 juil. 2008 à 07:11
Mahmah Messages postés 496 Date d'inscription lundi 17 septembre 2007 Statut Membre Dernière intervention 22 juin 2010 - 30 juil. 2008 à 15:33
Mahmah Messages postés 496 Date d'inscription lundi 17 septembre 2007 Statut Membre Dernière intervention 22 juin 2010 - 30 juil. 2008 à 15:33
A voir également:
- [C] Sprintf et transformation en octet
- 1 octet en bit ✓ - Forum Logiciels
- Transformer majuscule en minuscule word - Guide
- Application/octet-stream to pdf ✓ - Forum Powerpoint
- Transformer image en icone - Guide
- Application/octet-stream ✓ - Forum Logiciels
4 réponses
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
30 juil. 2008 à 09:24
30 juil. 2008 à 09:24
Je ne comprends pas bien ton histoire.
En fait, le fait que ça soit à l'envers m'étonne déjà.
pour moi, le sprintf permet d'écrire du texte dans une variable et fwrite écris en binaire. MAIS une sortie en hexadécimal (donnée par %X) écrit du texte, par exemple si ton entier vaut dix, tu écrira "0A" dans ton texte, ce qui correspond aux entier 55 et 70 (par exemple, je n'ai pas vérifié) ce qui une fois écri en binaire te donnera tout à fait autre chose.
en C, normalement (à vérifier avec sizeof), char vaut 1 octet, int 4, short 2.
Donc, défini un pointeur d'octet : char* head; (Il faut faire attention, char est souvent vu comme un caractère, mais c'est aussi un entier, ce qui m'intéresse ici)
alloue lui la bonne taille, puis rempli le :
*(head + decalage_en_octet)=(short)/* ou int */ variable_a_stoker
En fait, le fait que ça soit à l'envers m'étonne déjà.
pour moi, le sprintf permet d'écrire du texte dans une variable et fwrite écris en binaire. MAIS une sortie en hexadécimal (donnée par %X) écrit du texte, par exemple si ton entier vaut dix, tu écrira "0A" dans ton texte, ce qui correspond aux entier 55 et 70 (par exemple, je n'ai pas vérifié) ce qui une fois écri en binaire te donnera tout à fait autre chose.
en C, normalement (à vérifier avec sizeof), char vaut 1 octet, int 4, short 2.
Donc, défini un pointeur d'octet : char* head; (Il faut faire attention, char est souvent vu comme un caractère, mais c'est aussi un entier, ce qui m'intéresse ici)
alloue lui la bonne taille, puis rempli le :
*(head + decalage_en_octet)=(short)/* ou int */ variable_a_stoker
Mahmah
Messages postés
496
Date d'inscription
lundi 17 septembre 2007
Statut
Membre
Dernière intervention
22 juin 2010
125
30 juil. 2008 à 11:27
30 juil. 2008 à 11:27
Bonjour,
Un header de fichier respecte des spécifications qui en pratique permettent bien souvent de faire des structures. Ces structures pourront être écrites facilement dans un fichier avec un fwrite.
EDIT. : exemple FIN EDIT.
L'inversion est normale. C'est la simple différence entre les machines Big Endian et Little Endian. Quand un PC écrira 1 soit 0x00000001 pour un humain en 32 bits, il l'écrira en inversant les octets, soit 01 00 00 00. Un Mac PowerPC écrira 00 00 00 01. C'est comme ça. (voir Endianess sur wikipédia Ainsi, en regardant ton fichier ou tes données avec un éditeur héxa ou la mémoire avec un debuggueur, c'est inversé. Ce n'est pas un bug. ;-) Même un simple int i = 22; est physiquement écrit 16 00 00 00 en mémoire.
M.
Un header de fichier respecte des spécifications qui en pratique permettent bien souvent de faire des structures. Ces structures pourront être écrites facilement dans un fichier avec un fwrite.
EDIT. : exemple FIN EDIT.
L'inversion est normale. C'est la simple différence entre les machines Big Endian et Little Endian. Quand un PC écrira 1 soit 0x00000001 pour un humain en 32 bits, il l'écrira en inversant les octets, soit 01 00 00 00. Un Mac PowerPC écrira 00 00 00 01. C'est comme ça. (voir Endianess sur wikipédia Ainsi, en regardant ton fichier ou tes données avec un éditeur héxa ou la mémoire avec un debuggueur, c'est inversé. Ce n'est pas un bug. ;-) Même un simple int i = 22; est physiquement écrit 16 00 00 00 en mémoire.
M.
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
30 juil. 2008 à 13:21
30 juil. 2008 à 13:21
exact, une structure est l'idéal. J'avais pensé au bigEndian, mais dans mon souvenir ça changeais AB en BA... (je copierai 100 fois comment fait le big endian en vrai)
Pour en revenir aux structure :
struct A{
int BMPHeaderLenght;short ReservedBit;int DataOffset;...etc
}
et ensuite, pour écrire :
write(&A,sizeof(A),f);
Le souci, c'est qu'en utilisant des structures avec des données alterné comme ça, tu peux avoir des alignements et donc des problèmes d'écriture.
Pour en revenir aux structure :
struct A{
int BMPHeaderLenght;short ReservedBit;int DataOffset;...etc
}
et ensuite, pour écrire :
write(&A,sizeof(A),f);
Le souci, c'est qu'en utilisant des structures avec des données alterné comme ça, tu peux avoir des alignements et donc des problèmes d'écriture.
Mahmah
Messages postés
496
Date d'inscription
lundi 17 septembre 2007
Statut
Membre
Dernière intervention
22 juin 2010
125
30 juil. 2008 à 15:33
30 juil. 2008 à 15:33
Ah oui, en effet, il faut surveiller les alignements pour les membres la structure. Il n'y a pas de convention pour le faire mais bon nombre de compilateurs reconnaissent le :
Sinon on doit pouvoir dire à n'importe quel compilateur quel alignement utiliser, mais c'est mieux de le faire localement dans le code quand c'est possible pour éviter de pénaliser toutes les structures/classes du programme.
Merci,
M.
#pragma pack( push, 1 ) // alignement forcé de 1 octet // Déclaration de la variable du type de la structure ... // Ecriture/Lecture ... #pragma pack( pop )
Sinon on doit pouvoir dire à n'importe quel compilateur quel alignement utiliser, mais c'est mieux de le faire localement dans le code quand c'est possible pour éviter de pénaliser toutes les structures/classes du programme.
Merci,
M.