[C] fgets ne prend pas un de mes champs

Fermé
Meyfarth - 6 janv. 2008 à 11:22
 Meyfarth - 8 janv. 2008 à 08:11
Bonjour,

J'ai un souci assez ... bizarre.

Je dois faire un projet sur lequel on doit gérer une base de donnée, avec des structures. Le problème survient lors de l'ajout d'un client.
J'avais premièrement utilisé fflush(stdin) afin que mon fgets ne prenne pas en compte le retour chariot, puis j'ai vu que la plupart des compilateurs n'aiment pas ça, notament gcc. J'ai donc changé pour une fonction qui me vide le buffer, que voici en dessous :
void vider_buffer()
{
 int c;
 while ((c = getchar()) != '\n' && c != EOF); /* vide le tampon */
}


Avec le fflush(stdin), tout fonctionnait à merveille (jusqu'à ce que j'essaye de compiler avec gcc ^^)

Maintenant, il me fait un bug : il ne me prend pas le champ "date de naissance". Je ne comprends pas, parce que ce champ est situé en plein milieu et n'a rien de différent par rapport aux autres.

Voici le code de ma structure "client" :

typedef struct {
	long int id_client;
	char nom[MAX_NOM];
	char prenom[MAX_PRENOM];
	char CP[6];
	char date_naissance[10];
	char adresse[MAX_ADRESSE];
	char ville[MAX_VILLE];
	char n_permis[MAX_N_PERMIS];
}client;


Et voici le code de l'ajout de client :

void ajouter_client(client tab_client[],int *nb_client, int max_client)
{ 
  if(*nb_client < max_client)
  {
 tab_client[*nb_client].id_client = id_nouveau_client(tab_client,*nb_client); /*On prend la case "*nb_client" du tableau, afin de prendre la première case non utilisée*/
 vider_buffer();
 printf("Nom : ");
 fgets(tab_client[*nb_client].nom,50,stdin);
 tab_client[*nb_client].nom[strlen(tab_client[*nb_client].nom) - 1] = '\0'; /* Cette ligne sert à remplacer le retour à la ligne par le caractère de fin de chaîne de caractère */
 printf("Prenom : ");
 fgets(tab_client[*nb_client].prenom,50,stdin);
 tab_client[*nb_client].prenom[strlen(tab_client[*nb_client].prenom) - 1] = '\0';
 printf("Date de naissance (sous forme jj/mm/aaaa) : ");
 fgets(tab_client[*nb_client].date_naissance,15,stdin);
 tab_client[*nb_client].date_naissance[strlen(tab_client[*nb_client].date_naissance) - 1] = '\0';
 printf("Adresse : ");
 fgets(tab_client[*nb_client].adresse,100,stdin);
 tab_client[*nb_client].adresse[strlen(tab_client[*nb_client].adresse) - 1] = '\0';
 printf("Code postal : ");
 fgets(tab_client[*nb_client].CP,8,stdin);
 tab_client[*nb_client].CP[strlen(tab_client[*nb_client].CP) - 1] = '\0';
 printf("Ville : ");
 fgets(tab_client[*nb_client].ville,50,stdin);
 tab_client[*nb_client].ville[strlen(tab_client[*nb_client].ville) - 1] = '\0';
 printf("Num permis : ");
 fgets(tab_client[*nb_client].n_permis,20,stdin);
 tab_client[*nb_client].n_permis[strlen(tab_client[*nb_client].n_permis) - 1] = '\0';
 *nb_client = *nb_client + 1;
 printf("\n");
 }
 else
 {
  printf("Nombre maximum de clients atteint\n");   
 }
}


Mon problème vient donc du fait que lors de l'ajout du client, je peux ajouter, mais dès que j'essaye de l'afficher, le champ "date de naissance" est vide.

Voici le code d'affichage :

void afficher_client(client client_affiche)
{
 printf("ID : %d\nNom : %s\nPrenom : %s\nDate de naissance : %s\nAdresse : %s\nCode Postal : %s\nVille : %s\nNum de permis : %s\n",client_affiche.id_client,client_affiche.nom,client_affiche.prenom,client_affiche.date_naissance,client_affiche.adresse,client_affiche.CP,client_affiche.ville,client_affiche.n_permis);
}


Une idée d'où peut provenir le problème ?

7 réponses

fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
6 janv. 2008 à 13:55
Salut

Tu as fait un char [6] pour le CP, mets plutôt un char[7], et ça devrait marcher.
Si ça ne marche pas, donne le code en entier que je puisse tester.

Cordialement
0
Re !

En effet, ça fonctionne un peu mieux, mais il me reste un souci maintenant : il me colle l'adresse a la date de naissance.

Un exemple, quand je tape les infos suivantes :

Date de naissance : 06/02/1987
Adresse : 14 La rue de l'arbre

A l'affichage j'ai :

Date de naissance : 06/02/198714 La rue de l'arbre
Adresse : 14 La rue de l'arbre

C'est à ne plus rien y comprendre ...
0
Ah, j'ai trouve : j'ai mis 11 pour la date de naissance, car la date sous format jj/mm/aaaa contient 10 caractères ...

Merci de l'aide ! J'aimerais comprendre pourquoi ça me fait ça par contre ...
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
6 janv. 2008 à 18:31
Ah, tu stockes la date comme ça, dans ce cas là, je te conseille de mettre date de naisse à 12, sinon tu vas avoir un problème avec l'adresse.
Alors, explication :
Tu fais, fgets(...,stdin), ainsi l'utilisateur tape au clavier et valider, la chaîne va donc stocker le '\n' en fin de chaîne. Et la fonction, va rajouter le '\0' pour dire que c'est la fin de la chaîne.
Au final, tu as ta chaîne avec \n et \0 en fin. Il faut donc rajouter deux caractères et non un. D'où le CP[5+2] et la date de naissance [12+2].

Conséquence si tu mets +1 au lieu de +2 :
Le \0 va déborder, et comme tu as une structure, et que les variables sont contiguës, le \0 va se trouver en début de chaîne suivante.
Ainsi, la variable suivante n'apparaitra pas à l'écran car son premier caractère sera \0. Tu es dans ce cas obliger de refaire un fgets de la variable modifier.

N'hésite pas à poser des questions, si je n'ai pas été clair.

Cordialement
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
C'est bon, j'ai tout compris !

Merci bien, je n'étais pas au courant du fait que les variables étaient contigues dans une structure !
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
7 janv. 2008 à 18:33
Salut,

Attention, même si souvent les champs sont contiguës, la norme ISO ne l'impose pas, et donc ils ne le sont pas forcément.

0
Ok, ça dépend du compilateur donc ?
0