Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Taille de structure

40 réponses
Avatar
laurent Coanet
J'ai un petit problème avec la taille des structures contenant des char :

typedef struct {
unsigned char c1;
unsigned char c2;
} MaStruct;

un sizeof(MaStruct) renvoie 4 et non le 2 attentu... ce qui me pose problème
pour lire un fichier dont l'entête commence par des informations codées sur
un octet (et je n'ai évidement pas envie de lire chaque info une à une).

Comment résoudre ou détourner ce problème ?

10 réponses

1 2 3 4
Avatar
AG
Il y a des bits de padding dans ta structure, pour que ses éléments
soient alignés comme il faut en mémoire. Si tu veux lire tes données, il
faut les lire une a une si tu veux un code portable. Si tu ne te soucie
pas de la portabilité, tu peux t'amuser avec ton compilateur, pour le
forcer à ne pas utiliser de bits de padding.

Alexandre.

laurent Coanet wrote:
J'ai un petit problème avec la taille des structures contenant des char :

typedef struct {
unsigned char c1;
unsigned char c2;
} MaStruct;

un sizeof(MaStruct) renvoie 4 et non le 2 attentu... ce qui me pose problème
pour lire un fichier dont l'entête commence par des informations codées sur
un octet (et je n'ai évidement pas envie de lire chaque info une à une).

Comment résoudre ou détourner ce problème ?




Avatar
Antoine Leca
En c9nc87$492$, laurent Coanet va escriure:
J'ai un petit problème avec la taille des structures contenant des
char :

typedef struct {
unsigned char c1;
unsigned char c2;
} MaStruct;

un sizeof(MaStruct) renvoie 4 et non le 2 attentu...


Il me semble que c'est un sujet sur lequel nous nous sommes étendus ces
derniers jours (le sujet était "malloc et adresses paires", et on a
dérivé...) Je pense que tu vas trouver cette lecture instructive.

ce qui me pose
problème pour lire un fichier dont l'entête commence par des
informations codées sur un octet (et je n'ai évidement pas envie de
lire chaque info une à une).


???
J'ai dû louper plusieurs épisodes, là.

D'abord, la lecture: il faut faire attention à ouvrir avec fopen(..., "rb"),
mais ensuite avec fgetc(), cela roule tout seul... Et ne te préoccupe pas
des performances, getc utilise un tampon, cela va aller plus vite que si tu
essayes de faire mieux avec open+read!

Ensuite, en quoi une structure de DEUX éléments aide à lire un fichier
organisé en OCTET?


Antoine

Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', "laurent Coanet" wrote:

J'ai un petit problème avec la taille des structures contenant des char
:

typedef struct {
unsigned char c1;
unsigned char c2;
} MaStruct;

un sizeof(MaStruct) renvoie 4 et non le 2 attentu... ce qui me pose
problème pour lire un fichier dont l'entête commence par des
informations codées sur un octet (et je n'ai évidement pas envie de lire
chaque info une à une).


Mauvais design. Une structure C n'est absolument pas faite pour mapper un
flux de bytes (la preuve).

Comment résoudre ou détourner ce problème ?


Il faut utiliser un tableau de bytes (unsigned char en C) et extraire les
informations à la main (désolé!), quitte à les placer ensuite dans une
structure *à usage interne uniquement*.

--
-ed- get my email here: http://marreduspam.com/ad672570
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?libÉ9
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', AG wrote:

Il y a des bits de padding dans ta structure, pour que ses éléments


Tu veux dire des 'bytes' de padding!

--
-ed- get my email here: http://marreduspam.com/ad672570
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?libÉ9
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Tom
"Emmanuel Delahaye" a écrit dans le message de
news:

Mauvais design. Une structure C n'est absolument pas faite pour mapper un
flux de bytes (la preuve).


En fait j'effectue une lecture d'un fichier image bitmap. Je commence tout
d'abord par lire l'entête fichier, puis l'entête image, puis la palette et
enfin l'image en elle même.

Je croyais qu'il était plus propre de créer, pour les entête au moins, une
structure :

typedef struct {
unsigned char signature[2];
unsigned long int tailleFic
unsigned long int champsInco
unsigned long int offsetImgFic
} BMP_Header;

et de lire avec un fread(&maStruct,sizeof(BMP_Header),1,fic)


Comment résoudre ou détourner ce problème ?


Il faut utiliser un tableau de bytes (unsigned char en C) et extraire les
informations à la main (désolé!), quitte à les placer ensuite dans une
structure *à usage interne uniquement*.


Si je comprends bien, il ne me reste qu'à lire octet par octet, et de
convertir mes paquets de 2 en unsigned short et mes paquets de 4 en unsigned
long ?



--
-ed- get my email here: http://marreduspam.com/ad672570
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?libÉ9
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/



Avatar
Régis Troadec
"laurent Coanet" a écrit dans le message de
news:c9nc87$492$

Salut,

J'ai un petit problème avec la taille des structures contenant des char :

typedef struct {
unsigned char c1;
unsigned char c2;
} MaStruct;

un sizeof(MaStruct) renvoie 4 et non le 2 attentu... ce qui me pose
problème

pour lire un fichier dont l'entête commence par des informations codées
sur

un octet (et je n'ai évidement pas envie de lire chaque info une à une).
Comment résoudre ou détourner ce problème ?


Je ne comprends pas tout, tu veux lire un octet par le biais d'une structure
contenant deux unsigned char, peut-etre voulais tu dire lire un mot.
Si c'est un octet, tu peux utiliser simplement un unsigned char, sinon si
c'est deux octets que tu veux lire, un tableau de 2 unsigned char genre
unsigned char fileHeader[2]; puis un fread(fileHeader, 1, 2, fic); , fic
etant un fichier binaire ouvert. Ca sera valide et portable si CHAR_BIT (nb
bits pour type char, dans <limits.h>) vaut 8, ce qui est le cas pour
beaucoup d'implementations. L'application de masques sur fileHeader
(fileHeader[0] et fileHeader[1] en vrai) te permettra ensuite de recuperer
les infos que tu veux.

Regis

Avatar
Régis Troadec
"Tom" a écrit dans le message de
news:c9o52a$q0a$

Salut,

"Emmanuel Delahaye" a écrit dans le message de
news:

Mauvais design. Une structure C n'est absolument pas faite pour mapper
un


flux de bytes (la preuve).


En fait j'effectue une lecture d'un fichier image bitmap. Je commence tout
d'abord par lire l'entête fichier, puis l'entête image, puis la palette et
enfin l'image en elle même.

Je croyais qu'il était plus propre de créer, pour les entête au moins, une
structure :

typedef struct {
unsigned char signature[2];
unsigned long int tailleFic
unsigned long int champsInco
unsigned long int offsetImgFic
} BMP_Header;

et de lire avec un fread(&maStruct,sizeof(BMP_Header),1,fic)


Ca peut etre une solution (mauvaise) si tu maîtrises l'alignement de tes
membres de structures dans ton implementation mais c'est ce qu'il y a de
moins portable et c'est deconseille.


Comment résoudre ou détourner ce problème ?


Il faut utiliser un tableau de bytes (unsigned char en C) et extraire
les


informations à la main (désolé!), quitte à les placer ensuite dans une
structure *à usage interne uniquement*.


Si je comprends bien, il ne me reste qu'à lire octet par octet, et de
convertir mes paquets de 2 en unsigned short et mes paquets de 4 en
unsigned

long ?



Oui, (tjs avec CHAR_BIT = 8).

Regis



Avatar
Régis Troadec
"Régis Troadec" a écrit dans le message de
news:c9o6r3$f14$

"Tom" a écrit dans le message de
news:c9o52a$q0a$

Salut,

"Emmanuel Delahaye" a écrit dans le message de
news:

Mauvais design. Une structure C n'est absolument pas faite pour mapper
un


flux de bytes (la preuve).


En fait j'effectue une lecture d'un fichier image bitmap. Je commence
tout


d'abord par lire l'entête fichier, puis l'entête image, puis la palette
et


enfin l'image en elle même.

Je croyais qu'il était plus propre de créer, pour les entête au moins,
une


structure :

typedef struct {
unsigned char signature[2];
unsigned long int tailleFic
unsigned long int champsInco
unsigned long int offsetImgFic
} BMP_Header;

et de lire avec un fread(&maStruct,sizeof(BMP_Header),1,fic)


Ca peut etre une solution (mauvaise) si tu maîtrises l'alignement de tes
membres de structures dans ton implementation mais c'est ce qu'il y a de
moins portable et c'est deconseille.



Pas fini : par conséquent, lire le fichier en mettant les valeurs dans la
structure membre par membre.

BMP_header * st;
FILE * fic;

/* allocs + ouv. fichier */

fread(st->signature, 1, 2, fic);
fread(st->tailleFic, sizeof st->tailleFic, 1, fic);
fread(st->champsInco, sizeof st->champsInco, 1, fic);
fread(st->offsetImgFic, sizeof st->offsetImgFic, 1, fic);

/* etc ...*/

Regis



Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', "Régis Troadec" wrote:

Pas fini : par conséquent, lire le fichier en mettant les valeurs dans la
structure membre par membre.

BMP_header * st;
FILE * fic;

/* allocs + ouv. fichier */

fread(st->signature, 1, 2, fic);


Non, ça ne résout pas les problèmes d'endianness.

--
-ed- get my email here: http://marreduspam.com/ad672570
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?libÉ9
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', "Régis Troadec" wrote:

fic); , fic etant un fichier binaire ouvert. Ca sera valide et portable
si CHAR_BIT (nb bits pour type char, dans <limits.h>) vaut 8, ce qui est


La taille interne des char du C n'a aucune importance. Les bytes des flux
font toujours 8 bits (rien à voir avec le C).

--
-ed- get my email here: http://marreduspam.com/ad672570
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?libÉ9
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

1 2 3 4