Bonjour alors je suis étudiant en dut 1 informatique ( pas en France donc ) et j'avais notamment un projet de langage C où je dois créer un mini-logiciel de gestion des notes des étudiants.
Les informations des étudiants seront dans des fichiers CSV ( noms , date naissance etc ). J'étais parti sur l'idée de créer un fichier pour chaque information ( un pour le nom , un pour les prénoms etc ) mais je me disais que dans la suite, quand l'utilisateur voudra supprimer un étudiant, je devrais récupérer sa position dans un fichier et parcourir chaque fichier pour le supprimer ce qui n'est pas très propre dans le sens où d'après quelques recherches, il est possible de tout mettre dans un seul fichier et ainsi je n'aurais plus qu'un fichier à gérer ! ( bon il y a aussi les autres fichiers pour les notes , les matières etc ) .
Maintenant j'ai beau réfléchir et faire plusieurs tentatives , je n'arrive pas à avoir ce que je veux comme résultat donc je m'en remet à vous !
1 - Comment faire rentrer toutes les informations dans un fichier CSV en les séparant ( par un ";" par exemple d'après mes recherches mais qui ne se verrait pas dans le fichier )
Quand j'arriverais à la dernière info d'un enfant , j'aurais juste juste à écrire en même temps un "\n" pour que le prochain aille directement à la ligne
2 - Si je supprime un étudiant, il y aura alors un espace vide, un ou deux ça passe mais dans le cas de plusieurs étudiants supprimés ça rendrait le fichier pas très joli donc comment faire pour supprimer ces lignes ?
3 - Est-ce que mon idée de base tien toujours la route niveau propreté ? Le fait d'avoir plusieurs fichiers pour chaque info
je ne pense pas qu'il faille réfléchir sur les fichiers en eux-mêmes. Il faut avant tout avoir une représentation claire des données que tu vas manipuler, ensuite comment tu organises ça dans des structure de données dans ton programme.
Les fichiers csv ne seront manipulés que lors d'une sauvegarde ou d'un chargement …
je ne pense pas qu'il faille réfléchir sur les fichiers en eux-mêmes. Il faut avant tout avoir une représentation claire des données que tu vas manipuler, ensuite comment tu organises ça dans des structure de données dans ton programme.
Les fichiers csv ne seront manipulés que lors d'une sauvegarde ou d'un chargement …
Exactement j'ai une bonne vision d'ensemble du programme ( sachant qu'on a eu beaucoup d'indications )
On nous a donné un MCD qui nous permettait de connaitre les variables/structures à créer
De base le fichier contient ce séparateur ? Ou dois je l'ajouter manuellement ?
Comme je te l'ai déjà dit un fichier csv est un fichier texte. Tu dois donc l'écrire comme un fichier texte, en y écrivant le séparateur entre chaque champs et en allant à la ligne '\n' à la fin de chaque enregistrement.
Pipa a écrit:
Chaque nouvelle information se mettra sur une case adjacente jusqu'à que je rentre un "\n" ?
Dans le fichier, c'est le séparateur qui différencie chaque case, et la fin de ligne '\n' qui fait passer à la ligne suivante !
On ne sait rien de la complexité de ton programme. Quelle sont les opérations que tu veux effectuer? Comment les informations de chaque personne seront-elles saisies? Par exemple ... Au cas où ce ne serait pas encore clair ... Tu as une ligne de texte par personne, ça pourrait avoir l'air de ceci: Romulus;Tartempion;25;1996/04/24;math-78;physique-87 Albert;Einstein;1878/05/33;102;math-99;physique-100
Le Tout est souvent plus grand que la somme de ses parties.
On ne sait rien de la complexité de ton programme. Quelle sont les opérations que tu veux effectuer? Comment les informations de chaque personne seront-elles saisies? Par exemple ... Au cas où ce ne serait pas encore clair ... Tu as une ligne de texte par personne, ça pourrait avoir l'air de ceci: Romulus;Tartempion;25;1996/04/24;math-78;physique-87 Albert;Einstein;1878/05/33;102;math-99;physique-100
Globalement :
Gestion des étudiants : permet de gérer les informations sur les étudiant
Gérer des matières : permet de gérer les informations sur les matières
Gestion des classes : permet de gérer les informations sur les classes
Gestion des notes : permet de gérer les notes obtenues par les étudiants dans les différentes
matières
Les données sont demandées à l'utilisateur puis saisies dans un fichier texte
Mais c'est exactement comme l'exemple que t'as donné mais donc du coup les ";" je dois les mettre moi même après que l'utilisateur ait rentré une information ?
rouIoude a écrit:
Pipa a écrit:
De base le fichier contient ce séparateur ? Ou dois je l'ajouter manuellement ?
Comme je te l'ai déjà dit un fichier csv est un fichier texte. Tu dois donc l'écrire comme un fichier texte, en y écrivant le séparateur entre chaque champs et en allant à la ligne '\n' à la fin de chaque enregistrement.
Pipa a écrit:
Chaque nouvelle information se mettra sur une case adjacente jusqu'à que je rentre un "\n" ?
Dans le fichier, c'est le séparateur qui différencie chaque case, et la fin de ligne '\n' qui fait passer à la ligne suivante !
En fait l'ambiguïté vient du faite que j'ouvrais les fichiers csv avec Excell ce qui fait que j'ai plusieurs cellules et j'ai remarqué qu'on pouvait changer le séparateur ( il y a une option pour ) mais en mettant mes informations dans le fichier ainsi créé, c'est comme si le séparateur n'existait plus !
En fait l'ambiguïté vient du faite que j'ouvrais les fichiers csv avec Excell ce qui fait que j'ai plusieurs cellules et j'ai remarqué qu'on pouvait changer le séparateur ( il y a une option pour ) mais en mettant mes informations dans le fichier ainsi créé, c'est comme si le séparateur n'existait plus !
Et bien tu l'ouvres avec un éditeur de texte, et là tu le verra le séparateur !
Pipa a écrit:
Mais c'est exactement comme l'exemple que t'as donné mais donc du coup les ";" je dois les mettre moi même après que l'utilisateur ait rentré une information ?
je ne pense pas qu'il faille réfléchir sur les fichiers en eux-mêmes. Il faut avant tout avoir une représentation claire des données que tu vas manipuler, ensuite comment tu organises ça dans des structure de données dans ton programme.
Les fichiers csv ne seront manipulés que lors d'une sauvegarde ou d'un chargement …
Exactement j'ai une bonne vision d'ensemble du programme ( sachant qu'on a eu beaucoup d'indications )
On nous a donné un MCD qui nous permettait de connaitre les variables/structures à créer
- Edité par Pipa il y a environ 3 heures
Tu as un MCD … cool. Après le MCD vient le MPD. Cela te permettra de représenter les entités par des tableaux de structures dont les champs sont les attributs des entités (et de certaines relations suivant les cardinalités).
Tu auras sans doute intérêt par simplicité d'avoir un fichier CSV par tableau, et des fonctions dédiées pour la lecture et l'enregistrement de ces fichiers. C'est plus simple de tout réécrire que de t'amuser à modifier de façon fine des fichiers csv …
Pour les détails de la construction desdits fichiers tu trouveras une pléthore d'informations sur le net (merci google). Il faut juste comprendre que CSV signifie Comma Separated Values = Valeurs Séparées par des Virgules. Les anglophones utilisent la virgule comme caractère séparant les champs, dans le monde francophone il s'agit plus de point virgule. Il va falloir que tu vérifies quel caractère est utilisé si on te fournit des données de départ. Dans ce cas, tes structures sont toutes faites et tu n'as pas à réfléchir. En revanche si tu définis tout par toi-même alors tu as le choix.
Lire et écrire des fichiers CSV de base (n'implémentant pas toutes les fonctionnalités de la RFC 4180) s'effectue simplement avec des fscanf et fprintf.
je ne pense pas qu'il faille réfléchir sur les fichiers en eux-mêmes. Il faut avant tout avoir une représentation claire des données que tu vas manipuler, ensuite comment tu organises ça dans des structure de données dans ton programme.
Les fichiers csv ne seront manipulés que lors d'une sauvegarde ou d'un chargement …
Exactement j'ai une bonne vision d'ensemble du programme ( sachant qu'on a eu beaucoup d'indications )
On nous a donné un MCD qui nous permettait de connaitre les variables/structures à créer
- Edité par Pipa il y a environ 3 heures
Tu as un MCD … cool. Après le MCD vient le MPD. Cela te permettra de représenter les entités par des tableaux de structures dont les champs sont les attributs des entités (et de certaines relations suivant les cardinalités).
Tu auras sans doute intérêt par simplicité d'avoir un fichier CSV par tableau, et des fonctions dédiées pour la lecture et l'enregistrement de ces fichiers. C'est plus simple de tout réécrire que de t'amuser à modifier de façon fine des fichiers csv …
Pour les détails de la construction desdits fichiers tu trouveras une pléthore d'informations sur le net (merci google). Il faut juste comprendre que CSV signifie Comma Separated Values = Valeurs Séparées par des Virgules. Les anglophones utilisent la virgule comme caractère séparant les champs, dans le monde francophone il s'agit plus de point virgule. Il va falloir que tu vérifies quel caractère est utilisé si on te fournit des données de départ. Dans ce cas, tes structures sont toutes faites et tu n'as pas à réfléchir. En revanche si tu définis tout par toi-même alors tu as le choix.
Lire et écrire des fichiers CSV de base (n'implémentant pas toutes les fonctionnalités de la RFC 4180) s'effectue simplement avec des fscanf et fprintf.
Re
Alors le MPD on l'a déjà fait
Je ne m'amuse pas c'est juste que je me rendais compte qu'au fil du travail, j'avais trop de fichiers à gérer et la note qu'on aura dépend fortement du code et de la structure du projet
Si tu as un MPD qu'est-ce qui peut te bloquer pour le traduire ?
J'ai jamais dit que quelques chose me bloquait de ce côté là je voulais juste savoir si c'était possible d'utiliser un seul fichier csv pouvant englober plusieurs informations et si oui comment mettre les ";"
EDIT : Alors j'ai un problème avec ma fonction ( charger de remplir les informations des étudiants ) Le fichier des étudiants est bien présent dans le dossier mais rien ne s'écrit dedans et j'ai beau cherché/faire des modis rien ne marche
Voici la fonction :
void ajout_Etudiant(){
FILE *infEtudiant = NULL;
etudiant Etudiant;
infEtudiant = fopen("infosEtudiants.csv","r+");
// rewind(infEtudiant);
if (infEtudiant == NULL)
{
printf ("Désolé une erreur s'est produite dans la base de donnée !");
exit(0);
}
printf ("Rentrez le(s) prénom(s) de l'étudiant : \n");
scanf ("%s",Etudiant.prenom);
fprintf(infEtudiant,"%s;",Etudiant.prenom);
viderBuffer();
printf ("Rentrez le nom de l'étudiant : \n");
scanf ("%s",Etudiant.nom);
fprintf(infEtudiant,"%s;",Etudiant.nom);
viderBuffer();
printf ("Rentrez le numéro de l'étudiant : \n");
scanf ("%d",&Etudiant.numero);
fprintf(infEtudiant,"%d;",Etudiant.numero);
viderBuffer();
printf ("Rentrez le numéro du jour, le numéro du mois puis l'année de naissance de l'étudiant :\n");
scanf ("%d %d %d",&Etudiant.date_naissance.jour,&Etudiant.date_naissance.mois,&Etudiant.date_naissance.annee);
fprintf(infEtudiant,"%d/%s/%d\n",Etudiant.date_naissance.jour,Etudiant.date_naissance.mois,Etudiant.date_naissance.annee);
viderBuffer();
fclose(infEtudiant);
}
Que fait ta fonction viderBuffer() ? À mon avis, elle est inutile. Et tu n'as pas le pointeur vers le fichier comme paramètre. Sinon, ton code devrait assez bien ... fonctionner. Tu dis que tu peux donner plusieurs prénoms, par quoi seront-ils séparés? Si c'est un espace, tu risques de te faire jouer un tour pour le reste. Dans ce cas, essaies scanf("%[^\n]", Etudiant.prenom); Pour la date, tu lis le mois avec %d et tu écris avec %s ... tu n'as pas converti entre les deux.
J'ai fait un copier-coller de ton code. J'ai un Segmentation Fault parce que fprintf s'attend à un pointeur pour le mois, mais c'est un int.
J'ai fait la correction %s -> %d et tout fonctionne.
- Edité par PierrotLeFou 14 septembre 2021 à 4:15:47
Le Tout est souvent plus grand que la somme de ses parties.
pour t'éviter plein de problèmes de conception par la suite, il te faut écrire des fonctions ; une fonction ne devant faire qu'une chose à la fois (et le faire bien). Une fonction (qui effectue une action) devrait être nommée en utilisant un verbe. Donc une fonction ajouter_etudiant ne devrait qu'ajouter un étudiant et rien de plus, elle ne doit pas ouvrir un fichier, demander des infos et les ajouter sans vérifications … J'ai personnellement l'habitude de préfixer les noms de fonctions avec le nom des objets sur lesquels elles s'appliquent (dans la mesure du possible).
Dans ton code tu devrais plus avoir quelque chose comme :
une fonction ui_saisir_etudiant qui est une fonction qui permet de saisir les données d'un étudiant. Elle renverra idéalement un code qui permet de savoir si ça c'est bien passé, et dans ce cas une donnée valide est disponible, ou si ça ne c'est pas bien passé et dans ce cas elle renvoie un code qui explique le souci (mauvaise saisie, saisie interrompue par l'utilisateur, étudiant qui existe déjà, …) ;
une fonction bdd_inserer_etudiant qui ajoute dans un fichier un nouvel etudiant ;
une fonction bdd_remplacer_etudiant qui met les données d'un étudiant existant à jour ;
…
Si tu mélanges accès au fichier (à la bdd) avec des saisies, de l'affichage et de la création d'étudiant tu vas te retrouver avec une usine à gaz impossible à débuguer car impossible à comprendre.
Il faut aussi, avant de pisser du code, faire des choix :
est-ce qu'on gère tout en mémoire, en ne faisant que des sauvegardes dans des fichiers à la demande utilisateur ?
est-ce que chaque modif doit immédiatement être sauvée ? que faire en cas de modifications sur plusieurs tables ?
y a-t-il un mécanisme de roll back ?
…
Normalement, à chaque entité de ton MPD doit correspondre une structure C, à chaque table doit correspondre un tableau (ou liste ou équivalent) de structure …
Chaque structure doit être accompagnée de fonctions de création, d'accès et modifications (au minimum) …
Edit: typos (avec énormément de retard, désolé).
- Edité par White Crow 16 septembre 2021 à 9:39:13
Que fait ta fonction viderBuffer() ? À mon avis, elle est inutile. Et tu n'as pas le pointeur vers le fichier comme paramètre. Sinon, ton code devrait assez bien ... fonctionner. Tu dis que tu peux donner plusieurs prénoms, par quoi seront-ils séparés? Si c'est un espace, tu risques de te faire jouer un tour pour le reste. Dans ce cas, essaies scanf("%[^\n]", Etudiant.prenom); Pour la date, tu lis le mois avec %d et tu écris avec %s ... tu n'as pas converti entre les deux.
J'ai fait un copier-coller de ton code. J'ai un Segmentation Fault parce que fprintf s'attend à un pointeur pour le mois, mais c'est un int.
J'ai fait la correction %s -> %d et tout fonctionne.
- Edité par PierrotLeFou il y a environ 8 heures
Alors voici la fonction viderBuffer();
void viderBuffer()
{
int c = 0;
while (c != '\n' && c != EOF)
{
c = getchar();
}
}
Elle me sert à vider la touche "entrer" pour pas qu'elle se retrouve dans le prochain scanf ( nous n'avons pas encore étudié les saisies sécurisées et le prof préfère qu'on fasse avec ce qu'on a appris pour qu'on avance tous au même rythme )
Oui les prénoms seront séparés par un espace mais je n'ai pas trop compris le scanf("%[^\n]", Etudiant.prenom); Je pense me rabattre sur la fonction fgets du cours de langage C que je viens de reprendre ( saisie de texte sécurisée ) où également je viens de comprendre quelle était le problème des espaces !
Pour le fprintf avec le %s il s'agit d'une erreur de ma part car je voulais initialement que l'utilisateur rendre un mois en toute lettre mais je me suis dit qu'il serait préférable de le faire en nombre
Bon sur vos conseils à tous j'ai fait des modifs ( faire plus de fonctions )
Maintenant j'ai encore un problème :
Quand j'exécute le programme, il me met deux printf à la suite :
Rentrez le(s) pr├®nom(s) de l'├®tudiant(e) :
Rentrez le(s) nom(s) de l'├®tudiant(e) :
Ce qui veut dire qu'il saute la saisie du prénom et me met directement sur la saisie du nom ( j'ai beau cherché je trouve pas l'erreur )
Et donc dans mon fichier, il y a des caractères un peu bizarre qui sont écrits...
Avant rien ne s'écrivait dans le fichier mais quand j'ai inclus "ctype.h" ça a remarché et je ne me souvient à quoi servait cette bibliothèque
Voici le code ( un peu plus long effectivement j'en suis désolé )
void ajout_Etudiant(){
int valRetour=0;
etudiant Etudiant;
printf ("Rentrez le(s) prénom(s) de l'étudiant(e) : \n");
valRetour = saisie (Etudiant.prenom,50);
verif(valRetour);
saisieFichierChaine(Etudiant.prenom);
printf ("Rentrez le(s) nom(s) de l'étudiant(e) : \n");
valRetour = saisie(Etudiant.nom,30);
verif(valRetour);
saisieFichierChaine(Etudiant.nom);
printf ("Rentrez le numéro du jour, le numéro du mois puis l'année de naissance de l'étudiant :\n");
scanf ("%d %d %d",&Etudiant.date_naissance.jour,&Etudiant.date_naissance.mois,&Etudiant.date_naissance.annee);
saisieFichierDate(Etudiant.date_naissance.jour,Etudiant.date_naissance.mois,Etudiant.date_naissance.annee);
viderBuffer();
printf ("Rentrez l'email de l'étudiant : \n");
valRetour = saisie(Etudiant.email,100);
verif(valRetour);
saisieFichierChaine(Etudiant.email);
printf ("Rentrez le numéro de l'étudiant : \n");
scanf ("%d",&Etudiant.numero);
saisieFichierInt(Etudiant.numero);
viderBuffer();
}
int saisie(char *chaine, int longueur)
{
char *positionEntree = NULL;
if (fgets(chaine, longueur, stdin) != NULL)
{
positionEntree = strchr(chaine, '\n');
if (positionEntree != NULL)
{
*positionEntree = '\0';
}
return 1;
}
else
{
return 0;
}
}
void verif (int valeurRetournee)
{
if (valeurRetournee == 0)
{
printf ("Une erreur s'est produite ! Le programme va quitter...\n");
exit(0);
}
}
void saisieFichierChaine(char *chaineAecrire)
{
FILE *infEtudiant = NULL;
infEtudiant = fopen("informationsEtudiants.csv","a");
if (infEtudiant == NULL)
{
printf ("Désolé une erreur s'est produite dans la base de donnée !");
exit(0);
}
fprintf(infEtudiant,"%s;",&chaineAecrire);
fclose(infEtudiant);
}
void saisieFichierDate(int jour,int mois, int annee)
{
FILE *infEtudiant = NULL;
infEtudiant = fopen("informationsEtudiants.csv","a");
if (infEtudiant == NULL)
{
printf ("Désolé une erreur s'est produite dans la base de donnée !");
exit(0);
}
fprintf(infEtudiant,"%d/%d/%d;",&jour,&mois,&annee);
}
void saisieFichierInt(int entierAecrire)
{
FILE *infEtudiant = NULL;
infEtudiant = fopen("informationsEtudiants.csv","a");
if (infEtudiant == NULL)
{
printf ("Désolé une erreur s'est produite dans la base de donnée !");
exit(0);
}
fprintf(infEtudiant,"%d\n",entierAecrire);
}
Le format %s ne lit la ligne que jusqu'au premier espace. Le deuxième prénom sera ignoré si tu appelles viderBuffer() J'ai ensuite pensé que viderBuffer était ce que tu as fait. Dans ce cas précis, contrairement à ce qu'on t'a dit, je ne ferais pas une fonction. Ça se résume à ceci: while(getchar() != '\n'); // et rien de plus Si tu lis à la console, tu n'as pas besoin de tester EOF. Trop, ce n'est pas mieux que pas assez. À mon avis tu vas te noyer dans tes fonctions. Pour le scanf("%[^\n]", ...) ça veut dire "tout sauf une fin de ligne"
Le Tout est souvent plus grand que la somme de ses parties.
void ajout_Etudiant(){
int valRetour=0;
etudiant Etudiant;
viderBuffer();
printf ("Rentrez le(s) prénom(s) de l'étudiant(e) : \n");
valRetour = saisie (Etudiant.prenom,50);
verif(valRetour);
printf ("Rentrez le(s) nom(s) de l'étudiant(e) : \n");
valRetour = saisie(Etudiant.nom,30);
verif(valRetour);
printf ("Rentrez le numéro du jour, le numéro du mois puis l'année de naissance de l'étudiant :\n");
scanf ("%d %d %d",&Etudiant.date_naissance.jour,&Etudiant.date_naissance.mois,&Etudiant.date_naissance.annee);
viderBuffer();
printf ("Rentrez l'email de l'étudiant : \n");
valRetour = saisie(Etudiant.email,100);
verif(valRetour);
printf ("Rentrez le numéro de l'étudiant : \n");
scanf ("%d",&Etudiant.numero);
viderBuffer();
insererEtudiant(&Etudiant);
}
int saisie(char *chaine, int longueur)
{
char *positionEntree = NULL;
if (fgets(chaine, longueur, stdin) != NULL)
{
positionEntree = strchr(chaine, '\n');
if (positionEntree != NULL)
{
*positionEntree = '\0';
}
return 1;
}
else
{
return 0;
}
}
void verif (int valeurRetournee)
{
if (valeurRetournee == 0)
{
printf ("Une erreur s'est produite ! Le programme va quitter...\n");
exit(0);
}
}
void insererEtudiant(etudiant* Etudiant)
{
FILE *infEtudiant = NULL;
infEtudiant = fopen("informationsEtudiants.csv","a");
if (infEtudiant == NULL)
{
printf ("Désolé une erreur s'est produite dans la base de donnée !");
exit(0);
}
fprintf (infEtudiant,"%s;",Etudiant->prenom);
fprintf (infEtudiant,"%s;",Etudiant->nom);
fprintf (infEtudiant,"%d;",Etudiant->date_naissance.jour);
fprintf (infEtudiant,"%d;",Etudiant->date_naissance.mois);
fprintf (infEtudiant,"%s;",Etudiant->date_naissance.annee);
fprintf (infEtudiant,"%d;",Etudiant->numero);
fprintf (infEtudiant,"%s\n",Etudiant->email);
}
Effectivement les deux printfs étaient sûrement du à un "\n" dans le buffer et j'ai réparé plusieurs erreurs d'écriture sauf une seule :
Pour la date de naissance (jour mois et annee ) ainsi que le numero ( leur point commun est donc d'être des entiers ) j'ai la même valeur à chaque fois qui s'écrit dans le fichier à savoir : 6422236;6422240;�;6422052 (sauf le dernier qui diffère des deux derniers chiffres quelques fois )
J'ai l'impression que c'est des adresses
J'ai sûrement fait une erreur dans la syntaxe du passage de donnée ( je n'avais encore jamais fait de passage de donnée de type "structure" mais j'arrive pas à trouver l'erreur
J'ai également des warning sur mon fichier .h et après vérification je ne vois toujours pas le problème : ( le prototype est bien définit )
prototypes.h :
void viderBuffer();
void ajout_Etudiant();
void search_Etudiant();
void supp_Etudiant();
void modif_Etudiant();
void lister_Etudiant();
int saisie(char *chaine, int longueur);
void verif (int valeurRetournee);
// void insererEtudiant(char prenom[], char nom[], char email[], int numero, int jour, int mois, int annee);
void insererEtudiant(etudiant* Etudiant);
warnings :
In file included from main.c:6:0:
prototypes.h:10:22: error: unknown type name 'etudiant'
void insererEtudiant(etudiant* Etudiant);
^~~~~~~~
main.c: In function 'ajout_Etudiant':
main.c:127:5: warning: implicit declaration of function 'insererEtudiant' [-Wimplicit-function-declaration]
insererEtudiant(&Etudiant);
^~~~~~~~~~~~~~~
main.c: At top level:
main.c:158:6: warning: conflicting types for 'insererEtudiant'
void insererEtudiant(etudiant* Etudiant)
^~~~~~~~~~~~~~~
main.c:127:5: note: previous implicit declaration of 'insererEtudiant' was here
insererEtudiant(&Etudiant);
^~~~~~~~~~~~~~~
Malgrè ces erreurs, j'ai les mêmes problèmes au niveau des donnés ( expliqué plus haut )
Tu déplaces le problème ... Tu écris maintenant l'année avec le format %s alors que tu l'as lue en format %d Le compilateur ne connait pas la structure etudiant. Où l'as-tu mise? C'est pour ça que tu as un warning sur insererEtudiant
Places la définition avant les prototypes.
- Edité par PierrotLeFou 15 septembre 2021 à 2:04:58
Le Tout est souvent plus grand que la somme de ses parties.
Il faut bien garder à l'esprit que le compilateur lit les fichiers de haut en bas, donc s'il utilise un type (comme ta structure etudiant) il doit en avoir connaissance donc avoir déjà lu sa définition.
Dans ton fichier prototype.h quand il lit la déclaration de la fonction insererEtudiant il n'a pas connaissance de la structure etudiant.
Haha oui j'avais pas remarque le %s pour l'année encore un oubli :)*
En incluant le fichier des structures avant les prototypes, je n'ai plus de warning et tout marche à merveille merci à vous deux !
J'avais encore quelques petites questions ( oui encore ... )
1 - Au lieu d'écrire
Etudiant->date_naissance.jour
aurais-je pu écrire :
Etudiant->date_naissance->jour ?
2 - Pour retourner au menu précèdent , j'utilisais goto ( qui est un peu dangereux je trouve ) mais je me suis souvenu qu'il n'est pas interfonction je veux dire par là que si je met une étiquette dans le main et un goto dans ma fonction insererEtudiant j'ai le message : étiquette "retour2emeMenu" a été référencé mais n'est pas défini
J'ai pensé à mettre mes menu dans des fonctions mais ça me parait un peu compliqué avec les choix et tout
La réponse est non ! pour cela, il aurait fallu que date_naissance soit un pointeur.
Tu peux très bien mettre tes menus dans des fonctions, tu fais retourner un entier qui correspond à un ID de menu choisi. Tu peux utiliser les enum ou éventuellement des define pour rendre ces entiers plus explicites.
La réponse est non ! pour cela, il aurait fallu que date_naissance soit un pointeur.
Tu peux très bien mettre tes menus dans des fonctions, tu fais retourner un entier qui correspond à un ID de menu choisi. Tu peux utiliser les enum ou éventuellement des define pour rendre ces entiers plus explicites.
Si j'ai essayé et ça n'avait pas marché je me disais que je faisais erreur !*Mais c'est bizarre car etudiant étant un pointeur je me disais que date_naissance le serait aussi
Pour les menu avec des recherches j'ai pensé à pensé à créer un booléen qui dans le cas d'un retour , je lui donne la valeur 1 qui est retournée au main ! J'aurais mis un while(booléen) dans le main du coup !
Mais l'idée de les mettre dans des fonctions me parait plus explicite j'essayerais d'abord cette solution !
J'ai finalement séparé les informations dans le fichier par des "espaces" car les ";" rendait cela pas très joli
Merci quand même bien que je reviendrais avec d'autres questions vu la longueur du projet
Ce serait mieux que je recrée un nouveau sujet plutôt que de continuer à poser mes questions ici ? Car j'en aurais beaucoup ( même si je m'efforce de tout régler moi même et de faire plein de recherche dans le forum ) j'ai pas trop envie d'envahir le forum donc je pense continuer l'avancée de mon code ici ( sauf cas défavorable effectivement )
J'ai finalement séparé les informations dans le fichier par des "espaces" car les ";" rendait cela pas très joli
Et si le nom de famille est "De machin", ça va se passer comment lors de la lecure ? Et on s'en moque que le fichier soit joli ou non, il n'est pas destiné à être lu "brut"
- Edité par edgarjacobs 15 septembre 2021 à 15:53:26
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
J'ai finalement séparé les informations dans le fichier par des "espaces" car les ";" rendait cela pas très joli
Et si le nom de famille est "De machin", ça va se passer comment lors de la lecure ? Et on s'en moque que le fichier soit joli ou non, il n'est pas destiné à être lu "brut"
- Edité par edgarjacobs il y a environ 1 heure
En faite c'est parce que ça ne marche pas avec fscanf je viens d'essayer avec les espaces et même avec eux ça ne marche pas
Je vais continuer à réfléchir avant de vous envoyer le code en question
En faite c'est parce que ça ne marche pas avec fscanf je viens d'essayer avec les espaces et même avec eux ça ne marche pas !
Comme te l'a indiqué Edgar, les espaces, c'est une très mauvaise idée. Le point virgule était très bien.
Après si ça ne marche pas comme tu dis, c'est que tu utilises mal fscanf ! On suppose que tu essais de lire ton fichier ?
Oui je suis dans la fonction ou l'utilisateur recherche un étudiant
Je suis partit du principe que deux étudiants ne peuvent avoir le même numéro/même email donc l'utilisateur choisit quelle information il a en sa possession ( car je me suis dit que si c'est le nom/prenom/date naissance, beaucoup d'étudiants peuvent partager les mêmes informations et il existe déjà une fonction qui est chargée de lister les étudiants )
Je vais essayer de remettre les ";" et réparer fscanf si je peux
EDIT: voilà pour le moment le code ( qui ne marche pas très bien )
void search_Etudiant()
{
FILE* infEtudiant = NULL;
int choix_Recherche = 0,num = 0,continuer_avec_email =0;
char email[100];
etudiant Etudiant;
int temp=0;
infEtudiant = fopen("informationsEtudiants.csv","r");
if (infEtudiant == NULL)
{
printf ("Un problème inattendu s'est produit ! Le programme va quitter...\n");
exit(0);
}
printf ("Quelle information voulez vous utiliser ? Choississez : \n1. Le numero \n2. L'email\n");
scanf ("%d",&choix_Recherche);
while (choix_Recherche > 2 || choix_Recherche < 1)
{
printf ("Choix indisponible ! Veuillez réessayer :\n");
scanf ("%d",&choix_Recherche);
}
if (choix_Recherche == 1)
{
printf ("Rentrez le numéro de l'étudiant :\n");
scanf("%d",&num);
do
{
fscanf(infEtudiant,"%s;%s;%d/%d/%d;%d;%s",Etudiant.prenom,Etudiant.nom,&Etudiant.date_naissance.jour,&Etudiant.date_naissance.mois,&Etudiant.date_naissance.annee,&Etudiant.numero,Etudiant.email);
}
while (Etudiant.numero != num && feof(infEtudiant) == 0);
if (Etudiant.numero == num )
{
printf ("\nL'étudiant dont le numéro est %d a été retrouvé ! Voici ses informations : \n",num);
printf ("Nom : %s\nPrénom : %s\nDate de naissance : %d/%d/%d\nNumero : %d\nEmail : %s\n",Etudiant.nom,Etudiant.prenom,Etudiant.date_naissance.jour,Etudiant.date_naissance.mois,Etudiant.date_naissance.annee,Etudiant.numero,Etudiant.email);
}
// else
// {
// printf ("\nL'étudiant dont le numéro est %d n'a pas été trouvé !\nVoulez vous réessayer avec l'email ? \n1- OUI\n2. NON\n",num);
// scanf("%d",&continuer_avec_email);
// }
}
}
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Le Tout est souvent plus grand que la somme de ses parties.