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

remplir des structures

15 réponses
Avatar
nicolas
bonsoir a tous,

j aimerai faire une fonction generique pour remplir n importe quel type
de structure.


void remplir_struct(char **data, void *structur);

mon tableau est remplit de la facon suivante: deux cases par deux cases:

data[0] = "toto" /* la valeur */
data[1] = "str" /* le type */
data[2] = "84"
data[3] = "int"

et ainsi pouvoir remplir une structure de ce type

struct toto {
char *str;
int i;
};

je pensais pouvoir remplir le void *structur a coup de sizeof et de cast
mais je ne pense pas que ce soit une bonne idee..

j aimerai avoir vos lumiere sur ce probleme.

merci d'avance pour tout.

5 réponses

1 2
Avatar
nicolas
Emmanuel Delahaye wrote:
nicolas wrote on 23/01/05 :

[....]



j ai teste avec ta structure et surtout avec memcpy, ca marche nettement
mieux ...

merci d'avoir pris le temps de me repondre.

Avatar
Emmanuel Delahaye
nicolas wrote on 23/01/05 :
je remplis mon void **index avec les adresses de void *data, c est a dire que
j'index chaque element de mon zone memoire data.


Oui, mais la seul information don tu dispose est l'adresse. Il manauq
ela taille de l'élement et éventuellement son nombre, des fois que tu
veuilles faire des tableaux... (pour une chaine, par exemple)

pour remplir mon tableau je devrai donc faire quelque chose comme ca :

memcpy(index[2], &value, sizeof(int)); /* pour un int */


Oui, mais la façon 'intelligente' est de stocker ces infos une bonne
fois pour toutes, et donc d'utiliser une structure comme décrite ci
après :

Il est préférable de définir un format commun de conteneur:

typedef struct
{
size_t size; /* taille d'un element */
size_t nb; /* nombre d'elements */
void *address; /* adresse du debut du bloc */
}
cont_s;

et faire un tableau de ces elements...

/* statique */
cont_s a_cont[123];

ou

/* dynamique */
cont_s *p_cont = malloc (sizeof *p_cont * 123);


donc lorsque j ai un int je remplis ma stucture comme ceci ?:

.size = sizeof (int)
.nb = 1 /* il sera toujour a un ??! */


Si c'est element unique, oui. Si c'est un tableau, c'est le nombre
d'élements.

.address = une zone memoire de data ?


Oui, l'adresse de la zone de données allouée par malloc :

<pseudo-code>
.address = malloc (sizeof .size * .nb);
</>

dans ce cas pourquoi utilise une structure, j avoue etre completement perdu
la ...


Pour mémoriser les informations. Ensuite, on utilise des fonctions pour
manipuler les données (memcpy() etc.). ON passe l'adresse de la
structure, et la fonction sait ce qu'elle a à faire. C'est le princile
de la gestion des données par des fonctions.

D'autre part, on ne peut pas faire d'arithmetique de pointeurs avec un void
*.



je ne savais pas ... pourtant dans mes tests mon ptr avancait correctement
(ou du moins semblait)


C'est parfois supporté comme une extension par certains conpilateurs en
mode non conforme.

La programmation générique, c'est pas trop un sujet de débutant. Il
faut pas mal d'expérience pour en maîtriser tous les principes...

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"C is a sharp tool"


Avatar
nicolas
[...]

oui j ai mieux compris le principe maintenant merci :)

La programmation générique, c'est pas trop un sujet de débutant. Il faut
pas mal d'expérience pour en maîtriser tous les principes...

faut bien que je progresse :)


une tte derniere question voici le code qui j ai fait grace a tes
explications:

--------------------------------------------------------
#include <string.h>
#include <stdlib.h>

#define MASK "iiiiiiifiiiiffiiiiii"

typedef struct
{
size_t size; /* taille d'un element */
void *adr; /* adresse du debut du bloc */
}
cont_s;

size_t get_size(char type)
{
if (type == 'i')
return (sizeof(int));
if (type == 'f')
return (sizeof(float));
return (0);
}


int main()
{
void *data;
cont_s *index;

int count;
size_t current;
char *mask = MASK;

int value = 42;
float value_b = 0.4;
float *toto;

index = malloc(sizeof(cont_s) * strlen(MASK));
current = 0;
for (count = 0; count < strlen(MASK); count++)
{
index[count].adr = malloc(mask[count]);
printf("%d: %pn", count, index[count].adr);
index[count].size = get_size(mask[count]);
}
printf("%pn", index[2].adr);
memcpy(index[2].adr, &value, sizeof(int));
memcpy(index[7].adr, &value_b, sizeof(float));
toto = index[7].adr;
printf("%fn", *toto);
}
--------------------------------------------------------

ma question se pose au niveau de la recuperation des donnees:
dans l exemple je passe par un float * pour afficher le contenu de index[7]

ya t il un moyen d utiliser direcement le contenu de index[7] proprement ?

merci encore pour tout

Avatar
Emmanuel Delahaye
nicolas wrote on 23/01/05 :
#include <string.h>
#include <stdlib.h>

#define MASK "iiiiiiifiiiiffiiiiii"

typedef struct
{
size_t size; /* taille d'un element */
void *adr; /* adresse du debut du bloc */
}
cont_s;

size_t get_size(char type)
{
if (type == 'i')
return (sizeof(int));
if (type == 'f')
return (sizeof(float));
return (0);
}

int main()
{
void *data;
cont_s *index;

int count;
size_t current;
char *mask = MASK;

int value = 42;
float value_b = 0.4;
float *toto;

index = malloc(sizeof(cont_s) * strlen(MASK));
current = 0;
for (count = 0; count < strlen(MASK); count++)
{
index[count].adr = malloc(mask[count]);
printf("%d: %pn", count, index[count].adr);
index[count].size = get_size(mask[count]);
}
printf("%pn", index[2].adr);
memcpy(index[2].adr, &value, sizeof(int));
memcpy(index[7].adr, &value_b, sizeof(float));
toto = index[7].adr;
printf("%fn", *toto);
}

ma question se pose au niveau de la recuperation des donnees:
dans l exemple je passe par un float * pour afficher le contenu de index[7]

ya t il un moyen d utiliser direcement le contenu de index[7] proprement ?


Pas à ma connaissance. Je pense qu'il faut passer par des fonctions qui
font les calculs d'adresse[1] et le memcpy() qui vont bien. Je l'ai pas
déjà dit ça ?

----------
[1] pour moi, une variable 'simple', c'est un tableau qui s'ignore (un
tableau de taille 1...) d'où:

typedef struct
{
size_t size; /* taille d'un element */
size_t nb; /* nombre d'elements */
void *adr; /* adresse du debut du bloc */
}
cont_s;

voir les prototypes de fread()/fwrite(), qsort() etc.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Mal nommer les choses c'est ajouter du malheur au
monde." -- Albert Camus.

Avatar
nicolas

Pas à ma connaissance. Je pense qu'il faut passer par des fonctions qui
font les calculs d'adresse[1] et le memcpy() qui vont bien. Je l'ai pas
déjà dit ça ?



ok desole j ai du mal comprendre.

----------
[1] pour moi, une variable 'simple', c'est un tableau qui s'ignore (un
tableau de taille 1...) d'où:

typedef struct
{
size_t size; /* taille d'un element */
size_t nb; /* nombre d'elements */
void *adr; /* adresse du debut du bloc */
}
cont_s;

voir les prototypes de fread()/fwrite(), qsort() etc.



ok merci pour tout :)

1 2