Bonjour ,
je suis débutant en c , et j'aimerais créer une fonction qui remplisse un enregistrement
enregistrement :
Code:
1
2
3
4
5
6
7 struct produit { int idProd; char libPro[50]; float prixProd; };
merci d'avance
Version imprimable
Bonjour ,
je suis débutant en c , et j'aimerais créer une fonction qui remplisse un enregistrement
enregistrement :
Code:
1
2
3
4
5
6
7 struct produit { int idProd; char libPro[50]; float prixProd; };
merci d'avance
Salut !
Tu n'es pas très clair sur ce que tu veux faire. Tu veux, je pense, remplir une structure de ce type ! Au choix deux solutions :
- Tu créés une fonction qui prend en paramètre l'adresse d'une structure de ce type
- Tu créés une fonction qui retourne un pointeur sur une zone mémoire allouée dynamiquement, pointeur qui pointe bien entendu sur une structure de ce type
Le reste c'est à toi de faire, créé ta fonction du mieux que tu peux par rapport à tes besoins et montre ton code ici !
Voila la fonction que j'ai faite pour l'instant :
voila , pour un premier temps ,Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 struct produit remplir() { struct Personne p; p.idProd=1; p.libProd="test"; p.prixProd=20; return (p); }
est-ce que cette fonction permet bien de créer un enregistrement avec comme valeur respectives :
1
test
20
merci d'avance
oui effectivement
donc :
c ça ?Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 struct produit remplir() { struct Personne p; p.idProd=1; strcpy(p.libProd,test); p.prixProd=20; return (p); }
Ce que je ne comprend pas dans ton code, c'est qu'elle retourne une structure de type produit mais dans la fonction tu en utilise une de type Personne, cela ne me semble pas très cohérent.
Maintenant le mieux serait encore que ta fonction puisse prendre en paramètre les données qu'il te faut pour remplir cette structure et la retourner par la fonction ;)
oui tu as raison c'était une erreur .Citation:
Ce que je ne comprend pas dans ton code, c'est qu'elle retourne une structure de type produit mais dans la fonction tu en utilise une de type Personne, cela ne me semble pas très cohérent.
Maintenant effectivement je vais essayer de passer des variables en parametres . Mais je préféré commencé doucement , et je complique aprés chaque étapes "validé".Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 struct produit remplir() { struct produit p; p.idProd=1; strcpy(p.libProd,test); p.prixProd=20; return (p); }
Et j'ai encore plein de complication à ajouter ....
merci
Oui bien sûr, quand on débute c'est une bonne marche à suivre mais plus tard, il faudra concevoir ta fonction, même d'une point de vue algorithmique puis une fois au point, l'implémenter mais ca, ca viendra un peu plus tard mais il faudra y passer et tu verras, cela te fera gagner pas mal de temps !
Ta fonction est presque correcte, sauf que test n'est pas définit. Par ailleurs, la fonction strcpy() peut poser des problèmes de sécurité. J'utilise plus volontier strncpy() ou strncat(). Voilà un exemple mettant en oeuvre différentes stratégies pour remplir et/ou créer une instance de ta structure Produit:
ThierryCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 #include <stdio.h> #include <stdlib.h> #include <string.h> struct Produit { int idProd; char libPro[50]; float prixProd; }; /* Cette fonction remplit une variable de type structure Produit locale a la fonction et retourne la valeur de cette structure par copie. Si la taille d'une instance de struct Produit est grand, cette strategie peut causer des problemes de performance */ struct Produit remplir_produit_1(int id, char const *lib, float prix) { struct Produit p = {0, {0}, 0.0}; p.idProd = id; strncpy(p.libPro, lib, sizeof p.libPro - 1); p.prixProd = prix; return p; } /* Cette fonction prend un pointeur sur une variable de type structure produit en parametre et remplit directement la structure situee à l'adresse pointee */ void remplir_produit_2(struct Produit *p, int id, char const *lib, float prix) { if (p != NULL) { p->idProd = id; /* Copie securisee de lib dans p->libProd */ p->libPro[0] = '\0'; strncat(p->libPro, lib, sizeof p->libPro - 1); p->prixProd = prix; } } /* Cette fonction alloue dynamiquement de la memoire dans un espace qui s'appelle le tas, et l'adresse est placee dans un pointeur p de type pointeur sur struct Produit. Les champs de la structure pointee par p sont alors remplis et l'adresse stockee dans p est retournee. Important: c'est la fonction appelante qui a la responsabilite de liberer la memoire a l'aide de la fonction free() */ struct Produit *creer_produit(int id, char const *lib, float prix) { struct Produit *p = NULL; p = malloc(sizeof *p); if (p != NULL) { p->idProd = id; p->libPro[0] = '\0'; strncat(p->libPro, lib, sizeof p->libPro - 1); p->prixProd = prix; } return p; } /* Permet d'afficher la representation d'une variable de type struct Produit sur le flux de sortie standard */ void afficher_produit(struct Produit *p) { if (p != NULL) { printf("id: %d\n", p->idProd); printf("lib: %s\n", p->libPro); printf("prix: %.2f\n", p->prixProd); printf("\n"); } } int main(void) { struct Produit p; struct Produit *q = NULL; p = remplir_produit_1(1, "sucre, 1 kg", 1.5); afficher_produit(&p); remplir_produit_2(&p, 2, "farine, 1 kg", 1.2); afficher_produit(&p); q = creer_produit(3, "confiture, 1 pot", 3.5); if (q != NULL) { /* Faire quelque chose avec q */ afficher_produit(q); /* Libérer la memoire allouee dans creer_produit() */ free(q), q = NULL; } else { fprintf(stderr, "Allocation de mémoire impossible\n"); } return EXIT_SUCCESS; }
Salut,
Vu que je débute avec le chapitre " Allocation dynamique de mémoire ", je me suis posé quelques questions en voyant le code de THIERRY...surtout concernant cette ligne :
Donc j'ai compilé ce code tout en testant plusieurs écritures, et j'aimerais savoir ou se situe les différences :Code:p = malloc(sizeof *p);
Et comme rien n'est au hasard en C ,je c'est qu'il y'a bien une explication ^___^Code:
1
2
3 p = malloc(sizeof (*p) );// avec ou sans parenthèses sa compile p = malloc(sizeof (p) );// avec ou sans parenthèses sa compile p = malloc(sizeof (struct Produit) );// sans parenthèses sa ne compile pas
ahh aussi les parenthèses du sizeof ne sont pas indispensable si j'ai bien compris ?
j'ai aussi lu quelque part dans un cours que ces fonctions ( d'allocation mémoire ) doivent être transtypées afin de réserver de l'espace pour des types de données différents du CHAR .
comme ceci je pense :
p = (struct Produit*) malloc(sizeof *p);
P.S: Merci " Thierry Chappuis " ton code est très instructif et complet...
:!: sizeof p et sizeof *p ce n'est pas la même chose. p est le pointeur, *p est l'objet pointé. (il peut être beaucoup plus gros).
l'opérateur sizeof admet 2 types d'opérandes : objet ou (type).
'char' et non 'CHAR' (le C est sensible à la casse).Citation:
j'ai aussi lu quelque part dans un cours que ces fonctions (d'allocation mémoire ) doivent être transtypées afin de réserver de l'espace pour des types de données différents du CHAR .
comme ceci je pense :
p = (struct Produit*) malloc(sizeof *p);
Tu parles de pratiques ancestrales datant d'avant la normalisation. Depuis 1989, malloc() retourne void* et le transtypage (cast) n'est pas nécessaire (voire nuisible).
http://emmanuel-delahaye.developpez....tes.htm#malloc
MERCI ....c'est bien plus clair maintenant !!!
ceci dit je peut vous assurer que le programme c'est compilé et exécuté même avec :
Je sais que ceci est faux ,et c'est pour sa que je m'entonne :?Code:
1
2
3 p = malloc(sizeof p ); /* dans ce cas c'est la taille du pointeur non ? qui est bien plus petite que celle de la structure ! */
...merci encore...
C'est techniquement juste, mais ce n'est certainement pas ce que tu veux (allocation d'un bloc de la taille d'un pointeur).
Si tu utilises un objet dont la taille réelle est < à la taille voulue, le comportement est indéterminé (c'est comme pour un débordement de tableau).
ahh OK...je vois mieux ...:mrgreen::mrgreen::mrgreen:...beaucoup mieux...Merci
sizeof est un opérateur et pas une fonction. Les parenthèses sont nécessaire si l'opérande désigne un type. Ainsi, tu peux écrire:
maisCode:sizeof *p
doit utiliser des parenthèses.Code:sizeof (struct Produit)
Le grand avantage des lignes de code suivantes:
réside au niveau de la maintenance. Si un jour tu désires pour une raison x ou y changer le type de p, il te suffit de modifier sa définition.Code:
1
2 struct Produit *p = NULL; p = malloc(sizeof *p);
Thierry