IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Programme de prêt de ressources


Sujet :

C

  1. #1
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2020
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2020
    Messages : 15
    Points : 7
    Points
    7
    Par défaut Programme de prêt de ressources
    Bonsoir tout le monde !
    Je travaille actuellement sur un projet dans lequel je dois gérer un parc de ressources physiques, et le prêt de celles-ci entre différents utilisateurs. J'ai donc créé plusieurs fonctions qui permettent de créer un utilisateur, de créer des ressources, etc., mais je ne vous publie pas tout mon code car il y a plus de 1000 lignes.

    Je me retrouve confrontée à un problème auquel je ne trouve pas de solution. En effet, si vous lisez mon code, vous verrez qu'il y a un problème au niveau de la fonction recuperer_info_user() dans personne.c. Je souhaiterais que cette fonction récupère les informations d'un utilisateur dans le fichier json associé, et donc le numéro (et seulement le numéro) des ressources que possède cet utilisateur. Cependant voilà, je fais pour cela appel à la fonction set_ressource() dans ressource.c, qui a en paramètres le numéro, le nom, le type de la ressource et enfin l'emprunt. Mon soucis est que j'aimerais que seul le numéro de la ressource soit visible, mais je ne sais pas vraiment comment m'y prendre en sachant que je fais appel à la fonction set_ressource() et que je suis donc obligée de lui donner 4 paramètres. Toute aide est donc la bienvenue !


    personne.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    typedef struct user_info_s{
    	char num[20];                   // numéro (unique) de l'utilisateur dans le fichier
    	int admin;                      // si ce compte possède les droits administateurs
    	char ID[50];                    // 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;    
     
    User recuperer_info_user(char * file){  // Pour récupérer les infos d'un utilisateur dans le fichier associé
    	Ressource rsc = NULL;
        Ressource premier = NULL;
        User user = NULL;
        user = (User)malloc(sizeof(struct user_info_s)); 
     
        JSON_Value *root_value;
        JSON_Object *root_object;
        char t[32];
        JSON_Array *liste;
     
        root_value = json_parse_file(file);
        root_object = json_value_get_object(root_value);
     
    	user = set_user((char*)json_object_dotget_string(root_object, "Personne.num"), 
    	(int)json_object_dotget_number(root_object, "Personne.admin"),
    	(char*)json_object_dotget_string(root_object,"Personne.ID"),
        (char*)json_object_dotget_string(root_object, "Personne.nom"),
        (char*)json_object_dotget_string(root_object, "Personne.prenom"),
        (char*)json_object_dotget_string(root_object, "Personne.mdp"),
    	(char*)json_object_dotget_string(root_object, "Personne.mail"),
        (char*)json_object_dotget_string(root_object, "Personne.telephone"),
        (char*)json_object_dotget_string(root_object, "Personne.adresse"),
        (char*)json_object_dotget_string(root_object, "Personne.codepostal"),
        (char*)json_object_dotget_string(root_object, "Personne.ville"));
     
        liste = json_value_get_array(json_object_dotget_value(root_object, "Personne.liste_Ressource"));
     
       	for (int i = 0; i < json_array_get_count(liste); i++) {
            strcpy(t, json_array_get_string(liste, i));    
            if(i == 0)
                premier = set_ressource(t);
            else{
                rsc = set_ressource(t);        
                ajouter_ressource(premier, rsc);
            }
        }
     
        if(premier != NULL){
            set_premiere_ressource(user, premier);
        }
     
    	json_value_free(root_value);
        return user;
    }

    ressource.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    typedef struct ressource_s{
    	char *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;
     
    Ressource set_ressource(char *num, char *nom_ressource, char *type_ressource, int emprunt){  // 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);
    	set_nom_ressource(re, nom_ressource);
    	set_type_ressource(re, type_ressource);
    	set_emprunt_ressource(re, emprunt);
    	re->suivant = NULL;
    	return (re);
    }

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 721
    Points : 31 044
    Points
    31 044
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Je ne vois pas le type "User" que tu utilises allègrement. Il y a bien le type "user" contenant ta structure (avec la variable "user" en plus je me demande ce qu'en pense le compilateur) mais pas le type "User". Accessoirement je me demande comment tu ne te mélanges pas les pinceaux avec ces types si semblables eux-mêmes ayant des variables de même nom.
    Toutefois en voyant user = (User)malloc(sizeof(struct user_info_s)) je me dis que ce type "User" doit probablement masquer une étoile (ie typedef user* User) ce qui est la pire des choses à faire en C. En C on ne masque jamais un pointeur car on a besoin de savoir qu'on manipule un pointeur au moment où on le manipule. D'autant plus que masquer un pointeur ne fait pas disparaitre l'étoile. Suffit que tu aies besoin de passer "&user" à une fonction quelconque pour qu'elle soit obligée de déclarer un double pointeur qui serait alors User *pt (une étoile masquée mais pas la seconde) et là l'ambigüité prend alors une ampleur démesurée.

    Mais bon, masquer un pointeur c'est fragilisant mais c'est pas une erreur. Non. La principale erreur est de voir 3 ou 4 lignes plus loin user=set_user(...).
    Donc déjà à la base, écrire var=truc puis 3 lignes plus loin écrire var=autre_chose laisse entrevoir la grosse erreur de conception (pourquoi alors avoir stocké "truc" si on ne s'en sert pas) mais quand en plus le truc en question est une zone mémoire allouée laquelle se trouve alors irrémédiablement perdue ben ce n'est pas la peine de chercher plus loin. Soit tu as besoin d'allouer de la ram et tu stockes cette allocation dans "user" donc tu ne dois ensuite plus jamais écrire user=quoi que ce soit sous peine de planter ton truc ; soit tu n'as pas besoin de malloc et donc dans ce cas il faudrait que tu dises pourquoi tu l'as fait.

  3. #3
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2020
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2020
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    Bonsoir et merci pour votre réponse ! Alors tout d’abord j’utilise en fait le type User parce que je l’ai déclaré dans mon fichier personne.h de la manière suivante : typedef struct user_info_s *User;. Il est vrai que ce n’est peut-être pas la meilleure chose à faire mais c’est comme ça que j’ai appris et j’ai un peu de mal à faire autrement
    Concernant le malloc, je m’en sers mais à d’autres endroits de mon code, que je n’ai pas jugés nécessaires de mettre. A vrai dire cette fonction recuperer_info_user() me sert car je l’utilise dans un autre fichier .c, dans une fonction qui permet à un utilisateur de se connecter, à moins que je ne me trompe et que le malloc ne soit quand même pas nécessaire.
    Cependant, telle qu’elle est écrite, cette fonction fonctionne. Mon problème réside véritablement dans le fait que quand j’appelle la fonction set_ressource(), je fais uniquement appel au "num" des ressources, alors que cette fonction prend normalement pour paramètres d’autres variables (nom, type et emprunt). Par conséquent ce que je cherche à faire est de me débrouiller pour que je puisse utiliser cette fonction-là, tout en affichant uniquement le paramètre "num", mais je ne sais pas vraiment comment m’y prendre...

  4. #4
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 580
    Points : 7 712
    Points
    7 712
    Par défaut
    Citation Envoyé par charlotte000000 Voir le message
    Bonsoir et merci pour votre réponse ! Alors tout d’abord j’utilise en fait le type User parce que je l’ai déclaré dans mon fichier personne.h de la manière suivante : typedef struct user_info_s *User;. Il est vrai que ce n’est peut-être pas la meilleure chose à faire mais c’est comme ça que j’ai appris et j’ai un peu de mal à faire autrement
    C'est un gros problème si tu prends comme base une manière de travailler dangereuse!
    Citation Envoyé par charlotte000000 Voir le message
    Concernant le malloc, je m’en sers mais à d’autres endroits de mon code, que je n’ai pas jugés nécessaires de mettre. A vrai dire cette fonction recuperer_info_user() me sert car je l’utilise dans un autre fichier .c, dans une fonction qui permet à un utilisateur de se connecter, à moins que je ne me trompe et que le malloc ne soit quand même pas nécessaire.
    Pas nécessaire pourquoi pas, mais ici c'est une erreur de faire ça. La fait qu'un code ne plante pas immédiatement n'est pas une preuve qu'il n'est pas erroné
    Citation Envoyé par charlotte000000 Voir le message
    Cependant, telle qu’elle est écrite, cette fonction fonctionne.
    Non justement. Elle semble fonctionner! Sve@r t'a indiqué qu'il y a avait une erreur importante.
    Citation Envoyé par charlotte000000 Voir le message
    Mon problème réside véritablement dans le fait que quand j’appelle la fonction set_ressource(), je fais uniquement appel au "num" des ressources, alors que cette fonction prend normalement pour paramètres d’autres variables (nom, type et emprunt). Par conséquent ce que je cherche à faire est de me débrouiller pour que je puisse utiliser cette fonction-là, tout en affichant uniquement le paramètre "num", mais je ne sais pas vraiment comment m’y prendre...
    Ton problème initial n'est pas oublié, mais on s'y paume un peu à causes des incohérences actuelles du code, qu'il faut résoudre. Ça inclut la cohérence de ta question. Tu cherches à avoir une unique fonction qui fasse 2 choses différentes, alors pourquoi ne pas écrire une fonction supplémentaire avec moins de paramètres.

  5. #5
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2020
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2020
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    D’accord je comprends, je vais donc retirer le malloc de cette fonction, merci !
    A vrai dire mon problème est que la fonction set_ressource() sert à définir une ressource à partir d’éléments qu’on va lui donner à sa création (donc son numéro, son nom (ou titre), son type, et le fait de savoir si elle est empruntée ou non). Par conséquent si je fais une nouvelle fonction avec uniquement le numéro, cela risque de ne pas fonctionner car qu’adviendra t’il alors des autres paramètres de cette ressource ?

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 721
    Points : 31 044
    Points
    31 044
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par charlotte000000 Voir le message
    Bonsoir et merci pour votre réponse ! Alors tout d’abord j’utilise en fait le type User parce que je l’ai déclaré dans mon fichier personne.h de la manière suivante : typedef struct user_info_s *User;. Il est vrai que ce n’est peut-être pas la meilleure chose à faire mais c’est comme ça que j’ai appris et j’ai un peu de mal à faire autrement
    Oui c'est sûr que ta façon de coder ne peut être que le reflet de ce que ton prof de C t'a enseigné. Et effectivement on trouve des tas d'exemples sur le web où les profs (qui n'ont de professeur que le nom) conseillent de masquer l'étoile. Hé oui, solution de simplicité. Mieux vaut masquer une difficulté que d'apprendre à ses élèves à l'affronter. Et en plus je subodore que ces profs ne savent même pas eux-même comment l'affronter => j'ai vu le cas récemment d'un intervenant venu ici demander des conseils en Python qu'il débutait car, disait-il, il allait l'enseigner à la rentrée prochaine (ben oui bien sûr, tu connais ta date de naissance t'as qu'à faire prof d'histoire !!!)
    Mais bon, il vaut mieux que tu saches dès maintenant que
    • c'est une très mauvaise chose
    • finalement ça ne sert pas à grand chose
    • tôt ou tard tu devras affronter les conséquences de cette façon de faire (et ça risque d'arriver plus tôt que plus tard)
    • tôt ou tard tu réaliseras qu'il faut quand-même apprendre à manipuler l'étoile et là, inversement, vaut mieux plus tôt que plus tard (et en plus en réalité c'est pas si diffiicile que ça !!!)


    Citation Envoyé par charlotte000000 Voir le message
    Concernant le malloc, je m’en sers mais à d’autres endroits de mon code, que je n’ai pas jugés nécessaires de mettre. A vrai dire cette fonction recuperer_info_user() me sert car je l’utilise dans un autre fichier .c, dans une fonction qui permet à un utilisateur de se connecter, à moins que je ne me trompe et que le malloc ne soit quand même pas nécessaire.
    Ok, le souci n'est pas de savoir si malloc est/n'est pas nécessaire, le souci c'est que tu perds la zone allouée quand tu écris user=autre chose. Donc là c'est à toi d'en tirer les enseignements et rechecker toute cette partie.

    Citation Envoyé par charlotte000000 Voir le message
    Mon problème réside véritablement dans le fait que quand j’appelle la fonction set_ressource()...
    Alors là aussi je vois un possible gros souci. Cette fonction en elle-même semble correcte. Ce n'est qu'une bête fonction de création et remplissage de maillon de liste chainée. C'est surtout le maillon qui me pose souci. Car ce maillon ne contient que des pointeurs vides.
    Je réécris ton code en réduit (en ne laissant que ce qu'il est utile de voir)
    Exemple (réduit)
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    typedef struct ressource_s{
    	char *num;                     // numéro (unique) de la ressource dans le fichier
    	struct ressource_s* suivant;   // ressource suivante
    }ressource;
     
    Ressource set_ressource(char *num, char *nom_ressource, char *type_ressource, int emprunt){  // Définit une ressource à partir de son numéro (unique)
    	Ressource re = NULL;
    	re = malloc(sizeof(struct ressource_s));			// Le cast du malloc n'est pas necessaire mais n'est pas non plus interdit => c'est toi qui voit
    	set_num_ressource(re, num);
    	re->suivant = NULL;
    	return re;			// Le return n'est pas une fonction => pas de parenthèses
    }
    Et je m'interroge sur la fonction set_num_ressource(re, num) que tu n'as pas postée. Comment cette fonction est-elle écrite ???

    Plusieurs hypothèses
    1. la fonction est écrite proprement. Puisque le num doit aller dans un pointeur pour l'instant vide, elle alloue donc à ce pointeur la taille nécessaire pour stocker le num avant de le stocker effectivement
      Code c : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      void set_num_ressource(ressource *re, char *num) {
      	re->num=malloc((strlen(num) + 1) * sizeof(*re->num));
      	strcpy(re->num, num);
      }
      Il faudra aussi plus tard penser à libérer toute cette mémoire allouée sinon...
    2. la fonction est écrite sans réflexion et ne fait que recopier le pointeur num passé en paramètre dans le pointeur num de la structure
      Code c : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      void set_num_ressource(ressource *re, char *num) {
      	re->num=num;
      }
      Dans ce cas, pour n nums tu crées n maillons ayant tous copiés la même et unique adresse, celle du paramètre "num". Ce paramètre étant en plus local à la fonction, il n'a même plus de sens une fois la fonction "set_ressource()" terminée donc tu te retrouves avec une adresse ne correspondant plus à quoi que ce soit de valide (peut-être même c'est devenu entre temps l'adresse de tout autre chose) et c'est le crash assuré
    3. la fonction a bien conscience du souci décrit précédemment et, au lieu de copier l'adresse, copie le contenu de num. Toutefois elle le fait sans penser à allouer de la ram
      Code c : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      void set_num_ressource(ressource *re, char *num) {
      	strcpy(re->num, num);
      }
      Là aussi crash. Toutefois, dans ce cas précis la solution palliative est facile à mettre en place: suffit de changer la structure pour qu'elle contienne l'espace nécessaire à stocker son contenu
      Code c : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      typedef struct ressource_s{
      	char num[50+1];                     // numéro (unique) de la ressource dans le fichier AVEC L'ESPACE NECESSAIRE POUR LE STOCKER
      	struct ressource_s* suivant;   // ressource suivante
      }ressource


    Citation Envoyé par charlotte000000 Voir le message
    Par conséquent ce que je cherche à faire est de me débrouiller pour que je puisse utiliser cette fonction-là, tout en affichant uniquement le paramètre "num", mais je ne sais pas vraiment comment m’y prendre...
    Ah ben si une fonction attend 5 paramètres, il faut lui en passer 5. Ou alors repenser la fonction. Ou alors passer au C++ dans lequel on peut mettre des fonctions avec paramètres facultatifs.
    Ici visiblement il te faut repenser la fonction. Donc exemple possible:
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Ressource set_ressource(){  // Définit une ressource à partir de son numéro (unique)
    	Ressource re = calloc(1, sizeof(struct ressource_s));			// Calloc met tout à 0
    	return re;
    }
     
    void set_nom_ressource (ressource *re, char *nom) { ... }
    void set_type_ressource (ressource *re, char *type) { ... }
    Voilà. Ta fonction set_ressource n'attend plus rien. Donc ensuite ben quand tu as juste le nom tu appelles d'abord set_ressource() sans rien puis tu appelles après set_nom_ressource(). Si tu as juste le type tu appelles toujours set_ressource() sans rien puis tu appelles après set_type_ressource(). Et si tu as le nom et le type alors tu appelles toujours set_ressource() sans rien puis tu appelles après set_nom_ressource() puis après set_type_ressource().

  7. #7
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2020
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2020
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    Merci beaucoup pour toutes ces précisions, vos conseils m'aident beaucoup !
    Concernant la fonction set_num_ressource(), elle est écrite comme dans le 3ème cas que vous me proposez :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void set_num_ressource(Ressource rsc, char *num){  // Définit le numéro (unique) d'une ressource
    	strcpy(rsc->num, num);
    }
    Et comme j'utilise toujours ce même type de fonction, même dans personne.c, vous avez raison je vais attribuer une "case" de plus à mes tableaux car sinon ça risque de coincer quand je demande à un utilisateur d'entrer son numéro de téléphone ou son code postal par exemple.

    En ce qui concerne ma fonction set_ressource(), je ne peux pas utiliser le C++ tout d'abord parce que je ne sais pas l'utiliser , et ensuite parce que le projet que je dois faire doit être codé en C.
    J'ai bien compris ce que vous m'expliquiez, merci ! J'ai cependant une petite question : est-ce que cela ne risque pas de poser problème quand je vais vouloir créer une ressource ? En effet, dans mon projet je souhaite que lorsqu'une ressource est créée, celle-ci s'affiche à la fois dans un fichier json (un fichier par ressource, contenant toutes les informations à son sujet (donc num, nom, type et emprunt)) mais aussi dans un fichier .dat (toujours avec toutes les infos d'une ressource, mais cette fois il y aura un seul fichier contenant toutes les ressources, avec une ressource par ligne). Voici le code de la fonction qui va créer une ressource et son fichier json :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Ressource creer_ressource(char *num, char *nom_ressource, char *type_ressource, int emprunt){  // Pour créer une nouvelle ressource
    	char path[128];
    	emprunt = 0;
    	sprintf(path, "fichier/Ressource/%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+");  // On ouvre le fichier en lecture et écriture
     
    	json_object_dotset_string(root_object, "Ressource.num", 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, nom_ressource, type_ressource, emprunt);
    	return rsc;
    }
    Comme vous pouvez le voir, je fais ici appel à la fonction set_ressource(). Est-ce qu'il faut donc que je remplace l'avant-dernière ligne par plusieurs lignes du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Ressource rsc = set_num_ressource(num);
    Ressource rsc = set_nom_ressource(nom_ressource);
    ...
    J'aimerais aussi avoir une précision concernant une autre partie de mon programme qui me pose problème (j'en demande peut_être beaucoup haha mais c'est vrai que je suis un peu coincée ). Je souhaite écrire une fonction de recherche, qui recherchera chaque ressource par type dans le fichier .dat (selon le type que l'utilisateur va entrer), et qui permettra à ce même utilisateur d'emprunter la ressource voulue (en tapant son num dans le terminal). Je sais donc à peu près comment procéder : en faisant une sorte de menu qui va présenter à l'utilisateur tous les types de ressources existants (CD, DVD, outils, jeux vidéos, etc.) via des printf, ensuite il y aura un scanf du choix, un switch(choix) case, et dans chaque case je compte lire le fichier .dat contenant les ressources, ligne par ligne, et utiliser la fonction strstr() pour comparer dans chaque ressource l'élément "type_ressource" avec le type que je recherche (je ne sais pas si c'est très clair). Suite à cela, il faudrait créer et afficher un nouveau fichier .dat qui contiendra chaque ressource qui est du type que l'utilisateur a sélectionné en entrée. Il faudrait également que l'utilisateur rentre le "num" de la ressource qu'il souhaite emprunter, et je repérerai celle-ci avec un strncmp(), puisque le num de la ressource est le premier paramètre qui apparaît sur la ligne, et puisque dans mon code tous les "num" ont exactement la même taille. Jusque-là je pense savoir faire. Cependant cela coince au niveau de l'emprunt d'une ressource. En effet, j'ai crée une fonction emprunter_ressource(), mais je ne sais pas comment l'utiliser dans ce cas de figure-là.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void emprunter_ressource(Ressource rsc){  // Pour emprunter une ressource
    	// 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, "%s, %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
    }
    Je ne sais pas quel paramètre mettre en entrée de cette ressource, car dans ma fonction de recherche, je repère une chaîne de caractère, et pas une ressource directement. De plus, il faudrait que la ressource qu'il souhaite emprunter ne soit pas encore empruntée, et que donc la variable "emprunt" soit égale à 0, or je lis simplement un fichier .dat donc je ne sais pas vraiment comment repérer cette variable, à moins de créer en amont un fichier contenant uniquement les ressources qui ne sont pas empruntées, et afficher ce fichier-là directement dans cette fonction de recherche. Si vous avez quelques pistes n'hésitez pas à m'en faire part car je suis un peu coincée dans cette partie-là de mon code

    Edit : Pour mon soucis avec la variable "emprunt" je pense avoir trouvé une solution. Plutôt que de me compliquer la tâche en créant un nouveau fichier .dat "listeRessourcesLibres" qui m'obligerait à modifier plusieurs de mes fonctions, je pense "séparer" la variable "emprunt" du reste de mes variables par un "-" ou un ":" à la place de la virgule que j'utilisais auparavant. Ainsi, je n'aurai plus qu'à utiliser strstr() en prenant pour sous-chaîne "- 0" ou ": 0" pour repérer si une ressource est libre ou non, et je n'aurai plus qu'à afficher celles qui contiennent cette sous-chaîne !

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 721
    Points : 31 044
    Points
    31 044
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par charlotte000000 Voir le message
    Concernant la fonction set_num_ressource(), elle est écrite comme dans le 3ème cas que vous me proposez :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void set_num_ressource(Ressource rsc, char *num){  // Définit le numéro (unique) d'une ressource
    	strcpy(rsc->num, num);
    }
    Et voilà. Tu copies de la data dans un pointeur pointant vers que dalle. Remarque sur 3 façons possibles d'écrire cette fonction qui soit adaptée à ta structure il n'y en avait qu'une de correcte donc les probas étaient contre toi. Et t'as du bol car la solution est facile: tu remplaces ta structure par une analogue à celle-ci
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef struct ressource_s{
    	char num[nnn+1];                     // numéro (unique) de la ressource dans le fichier AVEC L'ESPACE NECESSAIRE POUR LE STOCKER (tu remplaces "nnn" par le nombre max de chiffres pour num)
    	struct ressource_s* suivant;   // ressource suivante
    }ressource

    Citation Envoyé par charlotte000000 Voir le message
    Et comme j'utilise toujours ce même type de fonction, même dans personne.c, vous avez raison je vais attribuer une "case" de plus à mes tableaux car sinon ça risque de coincer quand je demande à un utilisateur d'entrer son numéro de téléphone ou son code postal par exemple.
    Je ne comprends pas ce que tu entends par "case" mais si tu fais référence au "+1" que j'ai écrit tu n'y es pas. Le "+1" c'est l'espace pour stocker le '\0' nécessaire à toute string.

    Citation Envoyé par charlotte000000 Voir le message
    En ce qui concerne ma fonction set_ressource(), je ne peux pas utiliser le C++ tout d'abord parce que je ne sais pas l'utiliser , et ensuite parce que le projet que je dois faire doit être codé en C.
    Le C++ c'était une boutade. Ici on est en C. Remarque c'est bien que tu saches quand-même qu'en C++ la solution aurait été un peu plus simple.

    Citation Envoyé par charlotte000000 Voir le message
    Comme vous pouvez le voir, je fais ici appel à la fonction set_ressource(). Est-ce qu'il faut donc que je remplace l'avant-dernière ligne par plusieurs lignes du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Ressource rsc = set_num_ressource(num);
    Ressource rsc = set_nom_ressource(nom_ressource);
    ...
    Je crois que tu n'as pas bien saisi le concept d'inutilité qui arrive inévitablement chaque fois qu'une même variable est remplie 2 fois sans être lue entre temps. Je vais essayer d'être plus clair: tu prends un verre, tu le remplis de vin. Ensuite tu mets le vin dans l'évier puis tu le remplis d'eau. Essaye ensuite de retrouver le vin qui y était et dis-moi ce que tu en penses. Ben en prog (donc dans tous les langages et pas seulement en C) c'est pareil. Chaque fois que tu écriras var=truc puis (sans utiliser le contenu de var) var=autre chose, ce sera mauvais. Quel que soit le langage, quelle que soit la variable, quel que soit "truc" ou "autre chose", ce sera un souci de conception !!!.
    Alors parfois le souci n'aura pas d'importance (certains écrivent par exemple int i=0 puis plus bas for (i=1; ...; i++) et certains intervenants de ce forum soutiennent cette initialisation systématique ; moi-même aujourd'hui j'ai rempli une structure entière à 0 puis juste en dessous j'ai modifié un champ de cette structure ce qui correspond donc au cas que je décris mais je trouvais plus simple de tout mettre à 0 en une fois via memset() plutôt que de mettre à 0 tous les champs sauf un) ; mais parfois le souci engendrera bug ce qui est le cas ici.
    Accessoirement en plus ici les fonction set_XXX étant toutes void (ne retournant rien), je suis dubitatif à te voir essayer de récupérer ce qu'elles retournent...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Ressource rsc=set_ressource();
    set_num_ressource(rsc, num);
    set_nom_ressource(rsc, nom);
    set_type_ressource(rsc, type_ressource);
    set_emprunt_ressource(rsc, emprunt);
    !!!

    Citation Envoyé par charlotte000000 Voir le message
    J'aimerais aussi avoir une précision concernant une autre partie de mon programme qui me pose problème (j'en demande peut_être beaucoup haha mais c'est vrai que je suis un peu coincée ). Je souhaite écrire une fonction de recherche, qui recherchera chaque ressource par type dans le fichier .dat (selon le type que l'utilisateur va entrer), et qui permettra à ce même utilisateur d'emprunter la ressource voulue (en tapant son num dans le terminal). Je sais donc à peu près comment procéder : en faisant une sorte de menu qui va présenter à l'utilisateur tous les types de ressources existants (CD, DVD, outils, jeux vidéos, etc.) via des printf, ensuite il y aura un scanf du choix, un switch(choix) case, et dans chaque case je compte lire le fichier .dat contenant les ressources, ligne par ligne, et utiliser la fonction strstr() pour comparer dans chaque ressource l'élément "type_ressource" avec le type que je recherche (je ne sais pas si c'est très clair). Suite à cela, il faudrait créer et afficher un nouveau fichier .dat qui contiendra chaque ressource qui est du type que l'utilisateur a sélectionné en entrée. Il faudrait également que l'utilisateur rentre le "num" de la ressource qu'il souhaite emprunter, et je repérerai celle-ci avec un strncmp(), puisque le num de la ressource est le premier paramètre qui apparaît sur la ligne, et puisque dans mon code tous les "num" ont exactement la même taille. Jusque-là je pense savoir faire.
    Tant mieux parce que ce que tu décris là c'est carrément un mini-projet dans ton projet. Si tu crois que ça va se régler en une réponse sur le fofo... D'autant plus que tu as franchement de très très grosses lacunes. Regarde set_nom_ressource(). Elle n'a que 2 paramètres, n'a qu'une seule instruction, ne renvoie rien et pourtant tu écris allègrement Ressource rsc = set_nom_ressource(nom_ressource) sans que ça te choque !!!
    Désolé, il te faut vraiment reprendre les bases. Bases des pointeurs, base des fonctions, faire des mini-exemples de listes chainées et là tu pourras envisager ton projet.

    Citation Envoyé par charlotte000000 Voir le message
    Cependant cela coince au niveau de l'emprunt d'une ressource. En effet, j'ai crée une fonction emprunter_ressource(), mais je ne sais pas comment l'utiliser dans ce cas de figure-là.
    Ben malheureusemt... le but de la prog est de créer des outils qui répondent à un besoin, pas de créer des outils et d'essayer d'adapter ensuite le besoin pour qu'il colle aux outils créés.

  9. #9
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2020
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2020
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    En ce qui concerne le "+1" que vous évoquez, je faisais référence à ma structure dans personne.c, dans laquelle je me suis trompée et où je n'avais pas alloué assez d'espace pour les variables "cp" et "tel", oubliant ainsi l'espace nécessaire pour stocker '\0'.

    Vous avez raison, le code que j'ai écrit n'a pas de sens quand je le relis, je pense que j'ai un peu tout confondu et je vous remercie de m'avoir expliqué mon erreur.

    Concernant ma fonction de recherche, je sais très bien que mon problème ne va pas se régler en une seule réponse. J'ai bien compris ce que je dois faire et je sais que la méthode que je pense utiliser est correcte, mon problème, comme je l'ai indiqué précédemment, est que je ne sais pas vraiment comment affecter une ressource à un utilisateur qui souhaite l'emprunter, puisque j'utilise un fichier .dat. En effet, ma fonction emprunter_ressource() telle qu'elle est actuellement écrite me sert uniquement à ajouter les informations de la ressource qui va être empruntée (num, nom, type, emprunt, date d'emprunt) dans un fichier "listeEmprunt.dat", et à ensuite modifier la valeur de la variable "emprunt", pour qu'elle soit maintenant égale à 1 (je devrais d'ailleurs mettre cette dernière ligne un peu plus haut dans mon code maintenant que j'y repense). Et j'aimerais simplement modifier cette dernière (que j'avais écrite bien avant de penser à la fonction de recherche) car je sais que maintenant elle ne fonctionne pas avec ce que je souhaite faire.

    Je sais bien que j'ai quelques lacunes, c'est pour cela que je poste mon message dans un forum nommé "Débuter" : tout simplement parce que je DEBUTE en C. Je souhaite comprendre les potentielles erreurs que je peux faire dans mes programmes, et c'est bien pour cela que je sollicite votre aide. Rien ne sert donc d'être condescendant, car comme l'indique mon profil j'étudie, et la programmation n'est donc pas mon métier, je cherche juste à apprendre.

  10. #10
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 721
    Points : 31 044
    Points
    31 044
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par charlotte000000 Voir le message
    Citation Envoyé par charlotte000000 Voir le message
    Je travaille actuellement sur un projet dans lequel je dois gérer un parc de ressources physiques, et le prêt de celles-ci entre différents utilisateurs. J'ai donc créé plusieurs fonctions qui permettent de créer un utilisateur, de créer des ressources, etc., mais je ne vous publie pas tout mon code car il y a plus de 1000 lignes.
    Je sais bien que j'ai quelques lacunes, c'est pour cela que je poste mon message dans un forum nommé "Débuter" : tout simplement parce que je DEBUTE en C. Je souhaite comprendre les potentielles erreurs que je peux faire dans mes programmes, et c'est bien pour cela que je sollicite votre aide. Rien ne sert donc d'être condescendant, car comme l'indique mon profil j'étudie, et la programmation n'est donc pas mon métier, je cherche juste à apprendre.
    Ces deux discours ne sont pas cohérents. On ne se lance pas dans un projet de gestion de parc faisant plus de 1000 lignes quand ce n'est pas son métier, et qu'on débute. J'ai quelques notions de plomberie qui me permettent de me lancer à changer un joint, pas à refaire les canalisations de mon immeuble. Et au delà d'un certain seuil de "quelques lacunes" et de "potentielles erreurs", l'aide se résume en "recommence ton tuto de C depuis le début, tu perdras moins de temps" !!!

  11. #11
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2020
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2020
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    Je me lance dans un tel projet car c’est mon professeur qui me l’a demandé. Et oui, je suis bien débutante, j’ai commencé à apprendre ce langage de programmation cette année et ce projet-là est le premier "gros" devoir que je dois rendre. C’est pour cela que je ne possède pas encore tous les éléments dont j’ai besoin pour mener à bien ce projet, et c’est donc pour cette même raison que je poste un message sur ce forum, dans le but d’obtenir de l’aide de la part de personnes plus qualifiées que moi, qui sauront m’expliquer mes erreurs et qui m’aideront à en tirer des enseignements.
    Ainsi, si quelqu’un a des conseils pour m’aider à résoudre mes différents problèmes concernant l’emprunt d’une ressource, je suis preneuse !

  12. #12
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2020
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2020
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    J'ai finalement trouvé la solution à mon problème d'emprunt !
    J'ai tout simplement utilisé la fonction strtok() afin de séparer ma chaîne de caractères en plusieurs parties : nom, num, type et emprunt. J'ai ensuite mis ces éléments-là dans un nouveau fichier avec un fprintf(), avec un élément par ligne (ligne 1 : num, ligne 2 : nom, ligne 3 : type, ligne 4 : emprunt). Pour finir, j'ai juste eu à repérer ces lignes-là avec un if(ligne == 1){...} et ce jusqu'à la ligne 3, puis j'ai attribué le contenu de ces lignes à mes variables num, nom et type. Pour la variable "emprunt" je n'ai finalement rien eu à faire puisque quoi qu'il arrive les ressources affichées doivent être libres (donc "emprunt" doit valoir 0), j'ai donc initialisé la variable emprunt à 0 au début de mon code.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 24/12/2016, 18h43
  2. Réponses: 8
    Dernier message: 30/05/2013, 13h28
  3. besoin d'aide pour mon programme
    Par pouyoudu17 dans le forum Débuter avec Java
    Réponses: 11
    Dernier message: 28/05/2007, 22h18
  4. [langage] Besoin d'aide dans mon codage
    Par frees3x dans le forum Langage
    Réponses: 4
    Dernier message: 08/11/2006, 08h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo