Bonjour tout le monde !
J'ai un petit soucis dans mon code. En effet, j'ai plusieurs fichiers .h et .c mais lors de la compilation le message "dereferencing pointer to incomplete type" s'affiche. Je pense comprendre d'où vient le soucis mais je ne sais pas vraiment comment le résoudre.
Tout d'abord, j'ai mon fichier personne.h qui contient en particulier la déclaration d'une structure User, et personne.c associé qui contient la structure "développée".
personne.h
personne.cCode:
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 #define _PERSONNE_H_ #include "ressource.h" typedef struct user_info_s *User; // Pointeur sur la structure user_info_s (on la développera dans "personne.c") // getters char *get_num_user(User user); // Retourne le numéro (unique) d'un utilisateur (pour pouvoir récupérer tel ou tel utilisateur dans la liste) int get_is_admin(User user); // Retourne 1 si c'est un administrateur et 0 sinon char *get_id_user(User user); // Retourne l'identifiant d'un utilisateur (pour lui permettre de se connecter) char *get_nom_user(User user); // Retourne le nom d'un utilisateur char *get_prenom_user(User user); // Retourne le prénom d'un utilisateur char *get_mdp_user(User user); // Retourne le mot de passe chiffré d'un utilisateur char *get_mail_user(User user); // Retourne l'adresse mail d'un utilisateur char *get_telephone_user(User user); // Retourne le numéro de téléphone d'un utilisateur char *get_adresse_user(User user); // Retourne l'adresse d'un utilisateur char *get_codepostal_user(User user); // Retourne le code postal d'un utilisateur char *get_ville_user(User user); // Retourne la ville d'un utilisateur Ressource get_ressource_user(User user); // Retourne la première ressource d'un user void info_user(User us); // Affiche les informations de l'utilisateur // setters User set_user(char *num, int admin, char *ID, char *nom, char *prenom, char *mdp, char *mail, char *tel, char *adresse, char *cp, char *ville); // Définit un utilisateur void set_num_user(User user, char *num); // Définit le numéro (unique) d'un utilisateur void set_admin(User user, int admin); // Définit la variable "isAdmin" d'un utilisateur void set_id_user(User user, char *ID); // Définit l'identifiant d'un utilisateur void set_nom_user(User user, char *nom); // Définit le nom d'un utilisateur void set_prenom_user(User user, char *prenom); // Définit le prénom d'un utilisateur void set_mdp_user(User user, char *mdp); // Définit le mot de passe chiffré d'un utilisateur void set_mail_user(User user, char *mail); // Définit l'adresse mail d'un utilisateur void set_telephone_user(User user, char *tel); // Définit le numéro de téléphone d'un utilisateur void set_adresse_user(User user, char *adresse); // Définit l'adresse d'un utilisateur void set_codepostal_user(User user, char *cp); // Définit le code postal d'un utilisateur void set_ville_user(User user, char *ville); // Définit la ville d'un utilisateur char *creer_num_user(); // Crée un numéro (unique) pour un utilisateur char *creer_id_user(); // Crée un identifiant (unique) pour un utilisateur, pour qu'il puisse se connecter void set_premiere_ressource(User user, Ressource rsc); // Définit la première ressource d'un utilisateur User changer_mdp(User us); // Fonction qui permet de modifier le mot de passe (chiffré) d'un utilisateur User creer_user(char *num, int admin, char *ID, char *nom, char *prenom, char *mdp, char *mail, char *tel, char *adresse, char *cp, char *ville, Ressource rsc); // Fonction qui permet de créer un utilisateur avec toutes les informations à son sujet void ajouter_user_dans_liste(char *num, char *ID, char *mdp, char *nom, char *prenom, char *mail, char *tel, char *adresse, char *cp, char *ville); // Fonction pour ajouter un utilisateur dans un fichier .dat void supprimer_user_dans_liste(User user); // Fonction pour supprimer un utilisateur dans le fichier .dat User modifier_info_user(User user); // Fonction qui permet de modifier les informations d'un utilisateur void supprimer_user(User user); // Fonction qui permet de supprimer le fichier json d'un utilisateur
J'ai ensuite mon fichier ressource.h qui contient la déclaration d'une structure Ressource, et ressource.c associé qui contient la structure "développée".Code:
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "../include/ressource.h" #include "../include/personne.h" #include "../include/fonction.h" #include "../include/chiffrement.h" #include "../include/parson.h" #include "../include/affichage.h" #include "../include/chargement.h" #define CLEAR_STDIN { int c; while((c = getchar()) != '\n' && c != EOF); } typedef struct user_info_s{ char num[50]; // numéro (unique) de l'utilisateur dans le fichier int admin; // si ce compte possède les droits administateurs char ID[64]; // identifiant de l'utilisateur (pour se connecter) char nom[30]; // prénom de l'utilisateur char prenom[30]; // nom de l'utilisateur char mdp[50]; // mot de passe de l'utilisateur (pour se connecter) char mail[60]; // adresse mail de l'utilisateur char tel[10]; // numéro de téléphone de l'utilisateur char adresse[60]; // adresse de l'utilisateur char cp[5]; // code postal de l'utilisateur char ville[40]; // ville de l'utilisateur struct ressource_s* premier; // première ressource de l'utilisateur }user; // getters char *get_num_user(User user){ return user->num; } int get_is_admin(User user){ return user->admin; } char *get_id_user(User user){ return user->ID; } char *get_nom_user(User user){ return user->nom; } char *get_prenom_user(User user){ return user->prenom; } char *get_mdp_user(User user){ return user->mdp; } char *get_mail_user(User user){ return user->mail; } char *get_telephone_user(User user){ return user->tel; } char *get_adresse_user(User user){ return user->adresse; } char *get_codepostal_user(User user){ return user->cp; } char *get_ville_user(User user){ return user->ville; } void info_user(User us){ if (get_is_admin(us) == 1) // si l'utilisateur est un administrateur printf("--------------------------\n| ADMINISTRATEUR %s\n| \tNom : %s\n| \tPrénom : %s\n| \tIdentifiant : %s\n| \tMail : %s\n| \tTéléphone : %s\n| \tAdresse : %s\n| \tCodePostal : %s\n| \tVille : %s\n--------------------------\n", get_num_user(us), get_nom_user(us), get_prenom_user(us), get_id_user(us), get_mail_user(us), get_telephone_user(us), get_adresse_user(us), get_codepostal_user(us), get_ville_user(us)); else // si c'est juste un utilisateur printf("--------------------------\n| UTILISATEUR %s\n| \tNom : %s\n| \tPrénom : %s\n| \tIdentifiant : %s\n| \tMail : %s\n| \tTéléphone : %s\n| \tAdresse : %s\n| \tCode Postal : %s\n| \tVille : %s\n| \tNombre de ressources : %d\n--------------------------\n", get_num_user(us), get_nom_user(us), get_prenom_user(us), get_id_user(us), get_mail_user(us), get_telephone_user(us), get_adresse_user(us), get_codepostal_user(us), get_ville_user(us), nb_ressources((Ressource)get_ressource_user(us))); } // setters User set_user(char *num, int admin, char *ID, char *nom, char *prenom, char *mdp, char *mail, char *tel, char *adresse, char *cp, char *ville){ User us = NULL; us = (User)malloc(sizeof(struct user_info_s)); set_num_user(us, num); set_admin(us, admin); set_id_user(us, ID); set_nom_user(us, nom); set_prenom_user(us, prenom); set_mdp_user(us, mdp); set_mail_user(us, mail); set_telephone_user(us, tel); set_adresse_user(us, adresse); set_codepostal_user(us, cp); set_ville_user(us, ville); set_premiere_ressource(us, NULL); return us; } void set_num_user(User user, char *num){ strcpy(user->num, num); } void set_admin(User user, int admin){ user->admin = admin; } void set_id_user(User user, char *ID){ strcpy(user->ID, ID); } void set_nom_user(User user, char *nom){ strcpy(user->nom, nom); } void set_prenom_user(User user, char *prenom){ strcpy(user->prenom, prenom); } void set_mdp_user(User user, char *mdp){ strcpy(user->mdp, mdp); } void set_mail_user(User user, char *mail){ strcpy(user->mail, mail); } void set_telephone_user(User user, char *tel){ strcpy(user->tel, tel); } void set_adresse_user(User user, char *adresse){ strcpy(user->adresse, adresse); } void set_codepostal_user(User user, char *cp){ strcpy(user->cp, cp); } void set_ville_user(User user, char *ville){ strcpy(user->ville, ville); } char *creer_num_user(){ char *num = (char*)malloc(32); time_t temps; struct tm date; time(&temps); date=*localtime(&temps); strftime(num, 128, "%m%d%Y%H%M%S", &date); return num; } char *creer_id_user(){ } void ajouter_user_dans_liste(char *num, char *ID, char *mdp, char *nom, char *prenom, char *mail, char *tel, char *adresse, char *cp, char *ville){ FILE *listeUser = NULL; char path[64] = ""; sprintf(path, "fichier/Personne/%s.json", num); listeUser = fopen("fichier/Personne/listeUser.dat", "a"); // On ouvre le fichier "listeUser.dat", pour écrire à la fin de ce fichier fprintf(listeUser, "%s, %s, %s, %s, %s, %s, %s, %s, %s, %s \n", path, ID, mdp, nom, prenom, mail, tel, adresse, cp, ville); // On ajoute dans "listeUser.dat" les informations sur l'utilisateur que l'on ajoute à la liste fclose(listeUser); } void supprimer_user_dans_liste(User user){ // Pour supprimer un utilisateur dans le fichier .dat char chaine[128]; char *a; FILE *listeUserIn = fopen("fichier/Personne/listeUser.dat", "r"); // On ouvre le fichier "listeUser.dat" pour le lire FILE *listeUserOut = fopen("fichier/Personne/listeUserOut.dat", "w"); // On crée et on ouvre le fichier "listeUserOut" pour écrire dedans if(listeUserIn != NULL){ // si le fichier n'est pas vide while(fgets(chaine, 128, listeUserIn) != NULL){ a = strtok(chaine," "); if(strcmp(a, get_num_user(user)) != 0){ fprintf(listeUserOut, "%d \n", a); } } } else{ // si le fichier est vide error("Imposible d'ouvrir le fichier"); } fclose("fichier/Personne/listeUser.dat"); fclose("fichier/Personne/listeUserOut.dat"); remove("fichier/Personne/listeUser.dat"); // On supprime l'ancien fichier "listeUser.dat" rename("fichier/Personne/listeUserOut.dat", "fichier/Personne/listeUser.dat"); // Et on le remplace par le nouveau fichier "listeUserOut.dat", que l'on va ensuite renommer, et qui ne contiendra plus l'utilisateur que l'on voulait supprimer } User changer_mdp(User us){ int isMdpGood = 0; char new_mdp[32]; char new_mdpConfirm[32]; while(isMdpGood <= 0 && isMdpGood != -3){ printf("Nouveau mot de passe : "); scanf("%s", new_mdp); CLEAR_STDIN printf("Confirmez le mot de passe : "); scanf("%s", new_mdpConfirm); CLEAR_STDIN if(strcmp(new_mdp, new_mdpConfirm) == 0) isMdpGood = 1; if(isMdpGood <= 0){ printf("\n Mots de passe différents \n"); if(2 + isMdpGood > 0) printf("Il vous reste %d essais \n", 2 + isMdpGood); isMdpGood--; } if(isMdpGood == -3){ printf("\nEchec\n"); return us; } } FILE *fileIN; FILE *fileOUT; char line[128] = ""; char line_file[128] = ""; char ID[64]; char mdp[50]; char nom[30]; char prenom[30]; char mail[60]; char tel[10]; char adresse[60]; char cp[5]; char ville[40]; char json[64] = "fichier/Personne/"; strcpy(ID, get_id_user(us)); strcpy(mdp, get_mdp_user(us)); strcpy(nom, get_nom_user(us)); strcpy(prenom, get_prenom_user(us)); strcpy(mail, get_mail_user(us)); strcpy(tel, get_telephone_user(us)); strcpy(adresse, get_adresse_user(us)); strcpy(cp, get_codepostal_user(us)); strcpy(ville, get_ville_user(us)); sprintf(json, "fichier/Personne/%s.json", get_num_user(us)); char *ID_file; char *mdp_file; char *nom_file; char *prenom_file; char *mail_file; char *tel_file; char *adresse_file; char *cp_file; char *ville_file; char *json_file; int isEquals = 1; fileIN = fopen("fichier/Personne/listeUser.dat", "r"); // On ouvre le fichier "listeUser.dat" pour le lire fileOUT = fopen("fichier/Personne/listeUserOut.dat", "w"); // On ouvre le fichier "listeUserOut" pour écrire dedans if(fileIN != NULL){ while (fgets(line, 128, fileIN) != NULL){ strcpy(line_file, line); for(int i = 0; ((i < 10) && isEquals == 1); i++){ switch(i){ case 0: ID_file = strtok(line, ","); if(strcmp(ID, ID_file) != 0) isEquals = 0; break; case 1: mdp_file = strtok(NULL, ","); if(strcmp(mdp, mdp_file) != 0) isEquals = 0; break; case 2: nom_file = strtok(NULL, ","); if(strcmp(nom, nom_file) != 0) isEquals = 0; break; case 3: prenom_file = strtok(NULL, ","); if(strcmp(prenom, prenom_file) != 0) isEquals = 0; break; case 4: mail_file = strtok(NULL, ","); if(strcmp(mail, mail_file) != 0) isEquals = 0; break; case 5: tel_file = strtok(NULL, ","); if(strcmp(tel, tel_file) != 0) isEquals = 0; break; case 6: adresse_file = strtok(NULL, ","); if(strcmp(adresse, adresse_file) != 0) isEquals = 0; break; case 7: cp_file = strtok(NULL, ","); if(strcmp(cp, cp_file) != 0) isEquals = 0; break; case 8: ville_file = strtok(NULL, ","); if(strcmp(ville, ville_file) != 0) isEquals = 0; break; case 9: json_file = strtok(NULL, ","); if(strcmp(json, json_file) != 0) isEquals = 0; break; } } if(isEquals == 0) fprintf(fileOUT, "%s", line_file); isEquals = 1; } } else error("Impossible d'ouvrir le fichier."); fclose(fileIN); fclose(fileOUT); remove("fichier/Personne/listeUser.dat"); // On supprime l'ancien fichier "listeUser.dat" rename("fichier/Personne/listeUserOut.dat", "listeUser.dat"); // Et on le remplace par le nouveau fichier "listeUserOut.dat", que l'on va ensuite renommer, et qui contiendra le mot de passe modifié us = creer_user(get_num_user(us), get_is_admin(us), get_id_user(us), get_nom_user(us), get_prenom_user(us), chiffrement_mdp(new_mdp), get_mail_user(us), get_telephone_user(us), get_adresse_user(us), get_codepostal_user(us), get_ville_user(us), get_ressource_user(us)); ajouter_user_dans_liste(get_num_user(us), get_id_user(us), chiffrement_mdp(new_mdp), get_nom_user(us), get_prenom_user(us), get_mail_user(us), get_telephone_user(us), get_adresse_user(us), get_codepostal_user(us), get_ville_user(us)); return us; } User modifier_info_user(User user){ int isMailGood = 0; char new_mail[60]; char new_mailConfirm[60]; int isTelGood = 0; char new_tel[10]; char new_telConfirm[10]; int isAdresseGood = 0; char new_adresse[60]; char new_adresseConfirm[60]; int isCpGood = 0; char new_cp[5]; char new_cpConfirm[5]; int isVilleGood = 0; char new_ville[40]; char new_villeConfirm[40]; int choix; printf("Veuillez choisir les coordonnées à modifier."); printf("\t\t1 - Mail\n"); printf("\t\t2 - Téléphone\n"); printf("\t\t3 - Lieu de résidence\n"); scanf("%d", &choix); CLEAR_STDIN switch(choix){ case 1: // Pour modifier le mail while(isMailGood <= 0 && isMailGood != -3){ printf("Nouveau mail : "); scanf("%s", new_mail); CLEAR_STDIN printf("Confirmez le mail : "); scanf("%s", new_mailConfirm); CLEAR_STDIN if(strcmp(new_mail, new_mailConfirm) == 0) isMailGood = 1; if(isMailGood <= 0){ printf("\n Mails différents \n"); if(2 + isMailGood > 0) printf("Il vous reste %d essais \n", 2 + isMailGood); isMailGood--; } if(isMailGood == -3){ printf("\nEchec\n"); return user; } } break; case 2: // Pour modifier le numéro de téléphone while(isTelGood <= 0 && isTelGood != -3){ printf("Nouveau numéro de téléphone : "); scanf("%s", new_tel); CLEAR_STDIN printf("Confirmez le numéro de téléphone : "); scanf("%s", new_telConfirm); CLEAR_STDIN if(strcmp(new_tel, new_telConfirm) == 0) isTelGood = 1; if(isTelGood <= 0){ printf("\n Numéros de téléphone différents \n"); if(2 + isTelGood > 0) printf("Il vous reste %d essais \n", 2 + isTelGood); isTelGood--; } if(isTelGood == -3){ printf("\nEchec\n"); return user; } } break; case 3: // Pour modifier le lieu de résidence while(isAdresseGood <= 0 && isAdresseGood != -3){ // Pour modifier l'adresse printf("Nouvelle adressse : "); scanf("%s", new_adresse); CLEAR_STDIN printf("Confirmez l'adresse : "); scanf("%s", new_adresseConfirm); CLEAR_STDIN if(strcmp(new_adresse, new_adresseConfirm) == 0) isAdresseGood = 1; if(isAdresseGood <= 0){ printf("\n Adresses différentes \n"); if(2 + isAdresseGood > 0) printf("Il vous reste %d essais \n", 2 + isAdresseGood); isAdresseGood--; } if(isAdresseGood == -3){ printf("\nEchec\n"); return user; } } while(isCpGood <= 0 && isCpGood != -3){ // Pour modifier le code postal printf("Nouveau code postal : "); scanf("%s", new_cp); CLEAR_STDIN printf("Confirmez le code postal : "); scanf("%s", new_cpConfirm); CLEAR_STDIN if(strcmp(new_cp, new_cpConfirm) == 0) isCpGood = 1; if(isCpGood <= 0){ printf("\n Code postaux différents \n"); if(2 + isCpGood > 0) printf("Il vous reste %d essais \n", 2 + isCpGood); isCpGood--; } if(isCpGood == -3){ printf("\nEchec\n"); return user; } } while(isVilleGood <= 0 && isVilleGood != -3){ // Pour modifier la ville de résidence printf("Nouvelle ville : "); scanf("%s", new_ville); CLEAR_STDIN printf("Confirmez la ville : "); scanf("%s", new_villeConfirm); CLEAR_STDIN if(strcmp(new_ville, new_villeConfirm) == 0) isVilleGood = 1; if(isVilleGood <= 0){ printf("\n Villes différentes \n"); if(2 + isVilleGood > 0) printf("Il vous reste %d essais \n", 2 + isVilleGood); isVilleGood--; } if(isVilleGood == -3){ printf("\nEchec\n"); return user; } } break; default: return user; break; } FILE *fileIN; FILE *fileOUT; char line[128] = ""; char line_file[128] = ""; char ID[64]; char mdp[50]; char nom[30]; char prenom[30]; char mail[60]; char tel[10]; char adresse[60]; char cp[5]; char ville[40]; char json[64] = "fichier/Personne/"; strcpy(ID, get_id_user(user)); strcpy(mdp, get_mdp_user(user)); strcpy(nom, get_nom_user(user)); strcpy(prenom, get_prenom_user(user)); strcpy(mail, get_mail_user(user)); strcpy(tel, get_telephone_user(user)); strcpy(adresse, get_adresse_user(user)); strcpy(cp, get_codepostal_user(user)); strcpy(ville, get_ville_user(user)); sprintf(json, "fichier/Personne/%s.json", get_num_user(user)); char *ID_file; char *mdp_file; char *nom_file; char *prenom_file; char *mail_file; char *tel_file; char *adresse_file; char *cp_file; char *ville_file; char *json_file; int isEquals = 1; fileIN = fopen("fichier/Personne/listeUser.dat", "r"); // On ouvre le fichier "listeUser.dat" pour le lire fileOUT = fopen("fichier/Personne/listeUserOUT.dat", "w"); // On ouvre le fichier "listeUserOut" pour écrire dedans if(fileIN != NULL){ while (fgets(line, 128, fileIN) != NULL){ strcpy(line_file, line); for(int i = 0; ((i < 10) && isEquals == 1); i++){ switch(i){ case 0: ID_file = strtok(line, ","); if(strcmp(ID, ID_file) != 0) isEquals = 0; break; case 1: mdp_file = strtok(NULL, ","); if(strcmp(mdp, mdp_file) != 0) isEquals = 0; break; case 2: nom_file = strtok(NULL, ","); if(strcmp(nom, nom_file) != 0) isEquals = 0; break; case 3: prenom_file = strtok(NULL, ","); if(strcmp(prenom, prenom_file) != 0) isEquals = 0; break; case 4: mail_file = strtok(NULL, ","); if(strcmp(mail, mail_file) != 0) isEquals = 0; break; case 5: tel_file = strtok(NULL, ","); if(strcmp(tel, tel_file) != 0) isEquals = 0; break; case 6: adresse_file = strtok(NULL, ","); if(strcmp(adresse, adresse_file) != 0) isEquals = 0; break; case 7: cp_file = strtok(NULL, ","); if(strcmp(cp, cp_file) != 0) isEquals = 0; break; case 8: ville_file = strtok(NULL, ","); if(strcmp(ville, ville_file) != 0) isEquals = 0; break; case 9: json_file = strtok(NULL, ","); if(strcmp(json, json_file) != 0) isEquals = 0; break; } } if(isEquals == 0) fprintf(fileOUT, "%s", line_file); isEquals = 1; } } else error("Impossible d'ouvrir le fichier."); fclose(fileIN); fclose(fileOUT); remove("fichier/Personne/listeUser.dat"); // On ouvre le fichier "listeUser.dat" pour le lire rename("fichier/Personne/listeUserOut.dat", "listeUser.dat"); // Et on le remplace par le nouveau fichier "listeUserOut.dat", que l'on va ensuite renommer, et qui contiendra les coordonnées modifiées strcpy(user->mail, new_mail); strcpy(user->tel, new_tel); strcpy(user->adresse, new_adresse); strcpy(user->cp, new_cp); strcpy(user->ville, new_ville); user = creer_user(get_num_user(user), get_is_admin(user), get_id_user(user), get_nom_user(user), get_prenom_user(user), chiffrement_mdp(mdp), get_mail_user(user), get_telephone_user(user), get_adresse_user(user), get_codepostal_user(user), get_ville_user(user), get_ressource_user(user)); ajouter_user_dans_liste(get_num_user(user), get_id_user(user), chiffrement_mdp(mdp), get_nom_user(user), get_prenom_user(user), get_mail_user(user), get_telephone_user(user), get_adresse_user(user), get_codepostal_user(user), get_ville_user(user)); return user; } void supprimer_user(User user){ }
ressource.h
ressource.cCode:
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 #define _RESSOURCE_H_ #ifndef _PERSONNE_H_ #include "personne.h" #endif typedef struct ressource_s *Ressource; // Pointeur sur la structure ressource_s (on la développera dans "ressource.c") // getters int get_num_ressource(Ressource rsc); // Retourne le numéro (unique) d'une ressource (pour pouvoir récupérer telle ou telle ressource dans la liste) char *get_nom_ressource(Ressource rsc); // Retourne le nom d'une ressource (ex : "CD de Céline Dion", "jeu Animal Crossing : New Horizons", etc.) char *get_type_ressource(Ressource rsc); // Retourne le type d'une ressource (CD, livre, PC, outil, etc.) int get_emprunt_ressource(Ressource rsc); // Retourne 0 si la ressource est libre, 1 si elle est actuellement empruntée Ressource get_next_ressource(Ressource rsc); // Retourne la ressource suivante void info_ressource(Ressource r); // Affiche les informations de la ressource int nb_ressources(Ressource r); // Affiche le nombre de ressources int nb_ressources_empruntees(Ressource r); // Affiche le nombre de ressources empruntées int nb_ressources_disponibles(Ressource r); // Affiche le nombre de ressources disponibles en prêt (donc pas empruntées actuellement) // setters void set_num_ressource(Ressource rsc, int num); // Définit le numéro (unique) d'une ressource void set_nom_ressource(Ressource rsc, char *nom_ressource); // Définit le nom (ou titre) d'une ressource void set_type_ressource(Ressource rsc, char *type_ressource); // Définit le type d'une ressource void set_emprunt_ressource(Ressource rsc, int emprunt); // Dé finit si une ressource est empruntée ou non Ressource set_ressource(int num); // Définit une ressource à partir de son numéro (unique) Ressource creer_ressource(int num, char *nom_ressource, char *type_ressource, int emprunt); // Fonction pour créer une nouvelle ressource Ressource supprimer_ressource(Ressource r, Ressource rRm); // Fonction pour supprimer le fichier json d'une ressource Ressource verifier_suppression(Ressource r, int *isSupp); // Fonction pour vérifier si une ressource a été supprimée void ajouter_ressource_dans_liste(int num, char *nom_ressource, char *type_ressource, int emprunt); // Fonction pour ajouter une ressource dans un fichier .dat void supprimer_ressource_dans_liste(Ressource r); // Fonction pour supprimer une ressource dans le fichier .dat Ressource ajouter_ressource(Ressource rsc, Ressource nrsc); // Fonction pour ajouter une ressource à la liste chaînée char *liste_ressource_toString(Ressource rsc); // Fonction pour afficher la ressource dans le fichier void emprunter_ressource(Ressource rsc, User us); // Fonction pour emprunter une ressource void rendre_ressource(Ressource rsc, User us); // Fonction pour rendre une ressource empruntée
Ensuite, j'ai mon fichier fonction.h que j'ai créé à partir de fonctions ayant des variables de type User et Ressource en paramètres. Ces fonctions étaient initialement dans les fichiers personne.h et ressource.h mais je les ai mises dans ce nouveau fichier pour éviter les inclusions mutuelles entre personne.h et ressource.h.Code:
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "../include/ressource.h" #include "../include/personne.h" #include "../include/fonction.h" #include "../include/parson.h" #include "../include/affichage.h" #define CLEAR_STDIN { int c; while((c = getchar()) != '\n' && c != EOF); } #define couleur(param) printf("\033[%sm",param) // "31" correspond à la couleur rouge et "32" correspond au vert typedef struct ressource_s{ int num; // numéro (unique) de la ressource dans le fichier char *nom_ressource; // nom de la ressource (ex : "CD de Céline Dion", "jeu Animal Crossing : New Horizons", etc.) char *type_ressource; // type de la ressource (CD, livre, PC, outil, etc.) int emprunt; // 0 si la ressource est libre, 1 si elle est empruntée struct ressource_s* suivant; // ressource suivante }ressource; // getters int get_num_ressource(Ressource rsc){ return rsc->num; } char *get_nom_ressource(Ressource rsc){ return rsc->nom_ressource; } char *get_type_ressource(Ressource rsc){ return rsc->type_ressource; } int get_emprunt_ressource(Ressource rsc){ return rsc->emprunt; } Ressource get_next_ressource(Ressource rsc){ return rsc->suivant; } void info_ressource(Ressource r){ if (r =! NULL){ // si il existe au moins une ressource printf("--------------------------\n| RESSOURCE %s\n| \tNom : %s\n| \tType : %s\n| Empruntée ? (1 = oui, 0 = non) : %d\n--------------------------\n", get_num_ressource(r), get_nom_ressource(r), get_type_ressource(r), get_emprunt_ressource(r)); if (get_emprunt_ressource(r) == 0) // si la ressource est libre couleur("32"); // affiche en vert else // si la ressource est empruntée couleur("31"); // affiche en rouge } } int nb_ressources(Ressource r){ // Affiche le nombre de ressources if(r == NULL){ // s'il n'y a aucune ressource return 0; } else{ // s'il y a au moins une ressource int size = 0; Ressource rc = r; while (rc != NULL){ size++; rc = rc->suivant; } return size; } } int nb_ressources_empruntees(Ressource r){ // Affiche le nombre de ressources empruntées if(r == NULL){ return 0; } else{ int size = 0; Ressource rc = r; while(rc != NULL){ if((rc->emprunt) == 1){ // si la ressource est empruntée size++; } rc = rc->suivant; } return size; } } int nb_ressources_disponibles(Ressource r){ // Affiche le nombre de ressources disponibles en prêt (donc pas empruntées actuellement) if(r == NULL){ return 0; } else{ int size = 0; Ressource rc = r; while(rc != NULL){ if((rc->emprunt) == 0){ // si la ressource est libre size++; } rc = rc->suivant; } return size; } } // setters void set_num_ressource(Ressource rsc, int num){ rsc->num = num; } void set_nom_ressource(Ressource rsc, char *nom_ressource){ strcpy(rsc->nom_ressource, nom_ressource); } void set_type_ressource(Ressource rsc, char *type_ressource){ strcpy(rsc->type_ressource, type_ressource); } void set_emprunt_ressource(Ressource rsc, int emprunt){ rsc->emprunt = emprunt; } Ressource set_ressource(int num){ // Définit une ressource à partir de son numéro (unique) Ressource re = NULL; re = (Ressource)malloc(sizeof(struct ressource_s)); set_num_ressource(re, num); char *nom = NULL; set_nom_ressource(re, nom); char *type = NULL; set_type_ressource(re, type); re->emprunt = 0; re->suivant = NULL; return (re); } Ressource creer_ressource(int num, char *nom_ressource, char *type_ressource, int emprunt){ // Pour créer une nouvelle ressource char path[64]; sprintf(path, "fichier/Ressource/%d.json", num); JSON_Value *root_value = json_value_init_object(); JSON_Object *root_object = json_value_get_object(root_value); char *serialized_string = NULL; FILE *json_file = NULL; json_file = fopen(path, "w+"); json_object_dotset_number(root_object, "Ressource.num", (double)num); json_object_dotset_string(root_object, "Ressource.nom_ressource", nom_ressource); json_object_dotset_string(root_object, "Ressource.type_ressource", type_ressource); json_object_dotset_number(root_object, "Ressource.emprunt", (double)emprunt); serialized_string = json_serialize_to_string_pretty(root_value); fprintf(json_file, "%s", serialized_string); fclose(json_file); json_free_serialized_string(serialized_string); json_value_free(root_value); Ressource rsc = set_ressource(num); return rsc; } Ressource supprimer_ressource(Ressource r, Ressource rRm){ // à faire } void ajouter_ressource_dans_liste(int num, char *nom_ressource, char *type_ressource, int emprunt){ // Pour ajouter une ressource dans un fichier .dat FILE *listeRessource = NULL; char path[64]; sprintf(path, "fichier/Ressource/%d.json", num); listeRessource = fopen("fichier/Ressource/listeRessource.dat", "a"); // On ouvre le fichier "listeRessource.dat", pour écrire à la fin de ce fichier fprintf(listeRessource, "%s, %s, %d \n", nom_ressource, type_ressource, emprunt); // On ajoute dans "listeRessource.dat" les informations sur la ressource que l'on ajoute à la liste fclose(listeRessource); } void supprimer_ressource_dans_liste(Ressource r){ // Pour supprimer une ressource dans le fichier .dat char chaine[128]; char *a; FILE *listeRessourceIn = fopen("fichier/Ressource/listeRessource.dat", "r"); // On ouvre le fichier "listeRessource.dat" pour le lire FILE *listeRessourceOut = fopen("fichier/Ressource/listeRessourceOut.dat", "w"); // On crée et on ouvre le fichier "listeRessourceOut" pour écrire dedans if(listeRessourceIn != NULL){ // si le fichier n'est pas vide while(fgets(chaine, 128, listeRessourceIn) != NULL){ a = strtok(chaine, " "); if(strcmp(a, get_num_ressource(r)) != 0){ fprintf(listeRessourceOut, "%d \n", a); } } } else{ // si le fichier est vide error("Impossible d'ouvrir le fichier"); } fclose("fichier/Ressource/listeRessource.dat"); fclose("fichier/Ressource/listeRessourceOut.dat"); remove("fichier/Ressource/listeRessource.dat"); // On supprime l'ancien fichier "listeRessource.dat" rename("fichier/Ressource/listeRessourceOut.dat", "fichier/Ressource/listeRessource.dat"); // Et on le remplace par le nouveau fichier "listeRessourceOut.dat", que l'on va ensuite renommer, et qui ne contiendra plus la ressource que l'on voulait supprimer } Ressource ajouter_ressource(Ressource rsc, Ressource nrsc){ if(rsc == NULL){ rsc = nrsc; nrsc->num = 1000; } else{ Ressource rs = rsc; while (rs->suivant != NULL){ rs = get_next_ressource(rs); } rs->suivant = nrsc; nrsc->num = rs->num + 1; } return rsc; } char *liste_ressource_toString(Ressource rsc){ Ressource arsc = rsc; char *string = (char *)malloc(sizeof(char)*2048); char str[2048] = "["; while(arsc != NULL){ strcat(str, "\""); strcat(str, arsc->num); strcat(str, "\""); if(arsc->suivant != NULL){ strcat(str, ","); } arsc = arsc->suivant; } strcat(str, "]"); strcpy(string, str); return string; }
Voici donc le code de fonction.h et fonction.c.
fonction.h
fonction.cCode:
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 #ifndef _FONCTION_H_ #define _FONCTION_H_ #ifndef _PERSONNE_H_ #include "personne.h" #endif #ifndef _RESSOURCE_H_ #include "ressource.h" #endif Ressource get_ressource_user(User user); // Retourne la première ressource d'un user void set_premiere_ressource(User user, Ressource rsc); // Définit la première ressource d'un utilisateur User creer_user(char *num, int admin, char *ID, char *nom, char *prenom, char *mdp, char *mail, char *tel, char *adresse, char *cp, char *ville, Ressource rsc); // Fonction qui permet de créer un utilisateur avec toutes les informations à son sujet void emprunter_ressource(Ressource rsc, User us); // Fonction pour emprunter une ressource void rendre_ressource(Ressource rsc, User us); // Fonction pour rendre une ressource empruntée #endif
Et donc quand je tente de compiler, le message suivant s'affiche :Code:
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
102
103 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "../include/fonction.h" #include "../include/ressource.h" #include "../include/personne.h" #include "../include/parson.h" #include "../include/affichage.h" #include "../include/chargement.h" Ressource get_ressource_user(User user){ return user->premier; } void set_premiere_ressource(User user, Ressource rsc){ ((user->premier) = rsc); } User creer_user(char *num, int admin, char *ID, char *nom, char *prenom, char *mdp, char *mail, char *tel, char *adresse, char *cp, char *ville, Ressource rsc){ char path[64]; sprintf(path, "fichier/Personne/%s.json", num); JSON_Value *root_value = json_value_init_object(); JSON_Object *root_object = json_value_get_object(root_value); char *serialized_string = NULL; FILE *json_file = NULL; json_file = fopen(path, "w+"); json_object_dotset_string(root_object, "Personne.num", num); json_object_dotset_number(root_object, "Personne.admin", (double)admin); json_object_dotset_string(root_object, "Personne.id", ID); json_object_dotset_string(root_object, "Personne.prenom", prenom); json_object_dotset_string(root_object, "Personne.nom", nom); json_object_dotset_string(root_object, "Personne.mdp", mdp); json_object_dotset_string(root_object, "Personne.mail", mail); json_object_dotset_string(root_object, "Personne.telephone", tel); json_object_dotset_string(root_object, "Personne.adresse", adresse); json_object_dotset_string(root_object, "Personne.codepostal", cp); json_object_dotset_string(root_object, "Personne.ville", ville); json_object_dotset_value(root_object, "Personne.listeRessource", json_parse_string(liste_ressource_toString(rsc))); serialized_string = json_serialize_to_string_pretty(root_value); fprintf(json_file, "%s", serialized_string); fclose(json_file); json_free_serialized_string(serialized_string); json_value_free(root_value); User user = set_user(num, admin, ID, nom, prenom, mdp, mail, tel, adresse, cp, ville); set_premiere_ressource(user, rsc); return user; } void emprunter_ressource(Ressource rsc, User us){ // Récupère la date et l'heure à laquelle la ressource est empruntée char *timeS = (char *)malloc(32); time_t temps; struct tm date; time(&temps); date = *localtime(&temps); strftime(timeS, 128, "[%d-%m-%Y|%H:%M]", &date); FILE *listeEmprunt = fopen("fichier/Ressource/listeEmprunt.dat", "a"); // On ouvre le fichier "listeEmprunt.dat", pour écrire à la fin de ce fichier fprintf(listeEmprunt, "%d, %s, %s, %d, %s\n", rsc->num, rsc->nom_ressource, rsc->type_ressource, rsc->emprunt, timeS); // On ajoute dans "listeEmprunt.dat" les informations sur la ressource qui va être empruntée fclose(listeEmprunt); rsc->emprunt = 1; // "emprunt" prend donc la valeur 1, ce qui signifie que cette ressource est maintenant empruntée } void rendre_ressource(Ressource rsc, User us){ char chaine[128]; char *a; FILE *listeEmpruntIn = fopen("fichier/Ressource/listeEmprunt.dat", "r"); // On ouvre le fichier "listeEmprunt.dat" pour le lire FILE *listeEmpruntOut = fopen("fichier/Ressource/listeEmpruntOut.dat", "w"); // On crée et on ouvre le fichier "listeEmpruntOut.dat" pour écrire dedans if(listeEmpruntIn != NULL){ // si le fichier n'est pas vide while(fgets(chaine, 128, listeEmpruntIn) != NULL){ a = strtok(chaine, " "); if(strcmp(a, get_num_ressource(rsc)) != 0){ fprintf(listeEmpruntOut, "%d \n", a); } } } else{ // si le fichier est vide error("Imposible d'ouvrir le fichier"); } fclose("fichier/Ressource/listeEmprunt.dat"); fclose("fichier/Ressource/listeEmpruntOut.dat"); remove("fichier/Ressource/listeEmprunt.dat"); // On supprime l'ancien fichier "listeEmprunt.dat" rename("fichier/Ressource/listeEmpruntOut.dat", "fichier/Ressource/listeEmprunt.dat"); // Et on le remplace par le nouveau fichier "listeEmprunt.dat", que l'on va ensuite renommer, et qui ne contiendra plus la ressource qui a été rendue rsc->emprunt = 0; // "emprunt" prend donc la valeur 0, ce qui signifie que cette ressource est maintenant libre }
Auriez-vous donc une idée de comment régler ce problème ?Code:
1
2
3
4
5
6
7
8 gcc -o ./src/fonction.o -c ./src/fonction.c ./src/fonction.c: In function get_ressource_user: ./src/fonction.c:16:13: error: dereferencing pointer to incomplete type struct user_info_s return user->premier; ^~ ./src/fonction.c: In function emprunter_ressource: ./src/fonction.c:72:51: error: dereferencing pointer to incomplete type struct ressource_s fprintf(listeEmprunt, "%d, %s, %s, %d, %s\n", rsc->num, rsc->nom_ressource, rsc->type_ressource, rsc->emprunt, timeS); // On ajoute dans "listeEmprunt.dat" les informations sur la ressource qui va être empruntée