[C] : saisi : chaine à taille précise, espace

Résolu/Fermé
jeremiethe7 - 19 avril 2008 à 09:42
jerémiethe7 Messages postés 152 Date d'inscription dimanche 2 décembre 2007 Statut Membre Dernière intervention 27 février 2009 - 20 avril 2008 à 09:59
Bonjour,

j'ai un problème quand je saisi une chaine : quand je tape jean paul, il me prend seulement jean.
Voici mon code:

do
{
printf("Entrer le %s de la personne ( < a %d caracteres ):",intitule_question,taille_recue);
scanf("%50s",tampon);fflush(stdin);
}
while(strlen(tampon)>=(taille_recue+1));

je n'ai pas de soucis avec ma boucle do while, je l'ai mise pour le contexte.
Je prend une taille précise (taille recue qui sera inférieure a 50 de toute façon). J'ai fait ça pour éviter que l'utilisateur fasse bugger le programme quand il reste appuyé comme un sourd sur une touche et fasse ensuitte entrer, dépasant la taille max de la chaine.
Mon problème c'est donc que j'aimerai qu'il puisse prendre des noms composés.

Voilà merci si vous avez des idées ce serait simpa.
a++ je reste connecté.

5 réponses

lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
19 avril 2008 à 11:33
Salut,

remplace
scanf("%50s",tampon);fflush(stdin);

avec
fscanf("%s",taille_recue+1,stdin);
fflush(stdin) complétement inutile
fflush() a effet seulement pour les flux en écriture
0
salut lami20j,

j'ai éssayé le fscanf mais ça ne fonctionne pas car il ne s'agit pas de lire dans un fichier.

J'ai aussi essayé un scanf("%s",taille_recue+1,stdin);
ça compile mais quand je lance l'execution et que je viens par ce bout de code j'ai un message d'erreurs de windows.

++
0
lami20j je voulais rajouter que le fflush(stdin) sert a vider lamémoire du claier car j'en est besoin si l'utilisateur tappe un truc qui dépasse la taille_recue, ça reboucle et au lieu de lui redemander la question ça va passer et si on met un espace dans la 1ère boucle ça va prendre la 2ième sélection donc ça va poser problème.

voilà
a+++ et j'attend vos conseils.
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567 > jeremiethe7
19 avril 2008 à 13:11
fflush(stdin) sert a vider lamémoire

fflush vide le tampon en écriture
stdin c'est pour les flux en lecture

donc c'est illusoire fflush(stdin)

en revanche tu peux lire les caractères qui traînes avec une boucle sur un getchar par exemple
while ((c = getchar()) != '\n' && c != EOF)
    ;
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
19 avril 2008 à 13:06
Re,

j'ai éssayé le fscanf mais ça ne fonctionne pas car il ne s'agit pas de lire dans un fichier.
stdin c'est l'entrée standard
fscanf lit dans un fichier ou depuis l'entrée standard

peux-tu afficher le code complet?
aussi l'erreur que tu obtiens

merci
0
re,

voici mon code complet :

#include<stdio.h>
#include<string.h>
#include<conio.h>
#include<iostream.h>
#include<time.h>
#include<stdlib.h>

#define T 10 // 10 numeros dans un telephone
#define N 30 // 30 lettres maximum dans un nom ou prenom
#define M 50 // 50 caracteres pour une adresse email




//####################################################################################################

/**********************************La STRUCTURE Contact***********************************************

variables: chaines : numerotel[T+1], name[N+1], pren[N+1],adrmail[M+1];
*/
//####################################################################################################

//structure stockage contact (les données)
typedef struct {
char numerotel[T+1]; // on rajoute toujours +1 pour avoir la place pour le "\0"
char name[N+1], pren[N+1],adrmail[M+1];
}Contact;
///////////////////////////////////////////////////////////////////////////////////////////////////




//####################################################################################################

/**********************************La STRUCTURE fiche*************************************************

variables: Contact : UnContact : contient les informations (nom+prenom+tel+mail) d'un contact
pointeur de type fiche : p_suivant : pointe sur des jetons de type fiche
*/
//####################################################################################################

//structure liste chain?e (donn?e + pointeur)
typedef struct fiche{
Contact UnContact;
fiche *p_suivant;
}fiche;
///////////////////////////////////////////////////////////////////////////////////////////////////




//####################################################################################################

/**********************************La fonction majuscules*********************************************

variables: chaines : tampon : elle recoit une chaine du main et retourne vers le main une fois passée en maj
*/
//####################################################################################################
char *majuscules(char *tampon)
{
for (int i=0;i<strlen(tampon);i++) // pour mettre en majuscule le nom en entier
{
tampon[i]=toupper(tampon[i]); // pour mettre en majuscule lettre par lettre
}
return tampon; // on retourne la chaine de caractères
}
///////////////////////////////////////////////////////////////////////////////////////////////////



//####################################################################################################

/****************************La fonction verification_donne*******************************************

variables: chaines : tampon[M+1] : la taille est maxiamle pour accepter tout les types possibles (mail+nom+tel+prenom)
intitule_question : c'est le mot qui va changer entre les différentes questions a poser = mot clé de la question.
entières taille reçue : c'est la taille maximale admissible par la chaine en sortie de la fonction.
*/
//####################################################################################################
char *verification_donne(char *intitule_question,int taille_recue)
{
char tampon[M+1],lettre='0';
do
{
if (strcmp(intitule_question,"tel")==0) // si on lui demande le téléphone
{
while (strlen(tampon)!=10) // il faudra une taille de 10
{
printf("Entrer le %s de la personne ( < a %d caracteres ): ",intitule_question,taille_recue); // on stock les donnees dans les variables internes a la fonction
scanf("%10s",tampon);fflush(stdin); // on ne prend que les 10 premiers caractères tapéss e le reste on l'efface.
}
}
else
{
printf("Entrer le %s de la personne ( < a %d caracteres ):",intitule_question,taille_recue); // on stock les donnees dans les variables internes a la fonction
scanf("%50s",tampon);fflush(stdin); // on met ça dans une taille de 50, le reste on effacera.
}
}
while(strlen(tampon)>=(taille_recue+1)); // petit rappel : on vient de passer par le "chemin" différent du tel (attention pour le moment la taille est de 50 !!!! alors que la taille sera soit de 30 (nom + prenom) ou 50 mail) donc on bouclera seulement lorsque ta taille correspondra.
fflush(stdin); // on efface la mémoire clavier pour éviter les plantages si on revient dans le main ( par exemple dernier chiffre tapé 3, on partira dans ajouter un contact.)
if(strcmp(intitule_question,"mail")!=0) // on met en majuscules tout sauf les mails (pas d'importance pour le tel)
return majuscules(tampon); // on retourne la chaine
else
return tampon;
}
///////////////////////////////////////////////////////////////////////////////////////////////////



//####################################################################################################

/********************************La fonction creation_jeton*******************************************

variables: chaines : numero[T+1], nom[N+1], prenom[N+1], mail[M+1] : variables d'entrées de la fonction.
pointeur de type fiche : pointeur : gràce à ce pointeur on va mettre les informations du contact dans une variable de type fiche et Contact plus exactement.
*/
//####################################################################################################
void creation_jeton(fiche *pointeur,char numero[T+1],char nom[N+1],char prenom[N+1],char mail[M+1])
{
strcpy(pointeur->UnContact.numerotel,numero); // cette fonction copie les variables internes aux fonctions dans un jeton.
strcpy(pointeur->UnContact.name,nom);
strcpy(pointeur->UnContact.pren,prenom);
strcpy(pointeur->UnContact.adrmail,mail);
}
///////////////////////////////////////////////////////////////////////////////////////////////////





//####################################################################################################

/******************************La fonction contact_deja_present***************************************

variables: chaines : nouveautel : variable d'entrée de la fonction, c'est le tépléphone que l'utilisateur vient d'entrer.
pointeur de type pointeur de fiche : pp_liste : gràce à ce pointeur on va connaitre la liste chainée
fiche: ce pointeur va servir a parcourir la liste chainée sans toucher à pp_liste, notre pointeur de référence pour connaitre la tête de lecture
entiers : fin=0 : si fin passe a 1, on arretera les recherches (1 contact possède le téléphone ou fin de liste chainée)
r : si r vaut 1, c'est qu'un contact possède déja ce téléphone. On retourne r vers une autre fonction, c'est le résultat de l'apel qui vaut 0 ou 1.
*/
//####################################################################################################

// Lorsqu'on ajoute ou modifie un contact, il ne faut pas qu'au final 2 contacts aient le meme numero de telephone. Elle va donc parcourir toute la liste chainee pour regarder si un contact n'a pas deja ce numero
int contact_deja_present(char *nouveautel,fiche **pp_liste)
{
int fin=0,r=0;
fiche *ptr=*pp_liste; // le pointeur ptr est le pointeur qui va parcourir la liste chainee pp_liste, on ne va pas travailler avec pp_liste mais avec ptr pour ne pas faire de changement sur le pointeur de tete (pp_liste)
while(fin==0) //on cherche si la personne n'est pas deja dans l'agenda
{
if(ptr==NULL) //si la liste est vide, on peut pas la parcourir donc en faisant fin=1 on quitte la boucle while
fin=1;
else
{
if (strcmp(nouveautel,(*ptr).UnContact.numerotel)==0) // si on a le meme telephone, compa renvoie 1 donc on a fin =1 et on quitte la boucle
{
r=1;
fin=1;
}
else // sinon (si r=0) = (si on a pas encore trouve le meme numero dans la liste chainee)
{
if((*ptr).p_suivant==0) // si on est sur le dernier jeton alors on doit s'arreter la sinon beug
fin=1;
ptr=(*ptr).p_suivant; // sinon c'est qu'il y a encore des jetons a etudier
}
}
}
return r; // on retourne r a la fonction ajouter contact.
}
///////////////////////////////////////////////////////////////////////////////////////////////////




//####################################################################################################

/************************************La fonction afficher*********************************************

variables: char : touche : l'utilisateur devra faire un echap pour revenir vers le Menu Principal
pointeur de type fiche : pp_liste : gràce à ce pointeur on va connaitre la liste chainée
ptr : ce pointeur va servir a parcourir la liste chainée sans toucher à p_liste, notre pointeur de référence pour connaitre la tête de lecture
entiers : fin=0 : si fin passe a 1, on arretera les recherches (fin de liste chainée).
*/
//####################################################################################################

// fonction afficher qui affiche la liste de tous les jetons
void afficher(fiche *p_liste)
{
int fin=0;
char touche='0';
fiche *ptr=p_liste; // un pointeur de type fiche qui pointe sur la tete de la liste chainee
system("cls");
printf("------------------ liste des contact -----------------\n\n");
if(p_liste==NULL)
{
fin=1;
}
else// si la liste n'est pas vide
{
while(fin==0)
{
printf("%s %s\n\tTelephone : %s\tE-mail : %s\n",(*ptr).UnContact.name,(*ptr).UnContact.pren,(*ptr).UnContact.numerotel,(*ptr).UnContact.adrmail); // on affiche le jeton
if((*ptr).p_suivant==0) // si le pointeur p_suivant de la fiche est null (si on se trouve dans le dernier jeton de la liste)
fin=1;
ptr=(*ptr).p_suivant; //on passe a la fiche suivante
}
free(ptr);
}
if(p_liste!=NULL)
printf("ERREUR : Repertoire vide\n\nECHAP : revenir au Menu du telephone");
else
printf("\nECHAP : revenir au Menu du telephone");
while(touche!=27)
{
if (kbhit()) // pour ressortir il faudra touche=27
touche=getch();
}
}


//####################################################################################################

/***********************************La fonction ecrire_fichier****************************************

variables: char : touche : l'utilisateur devra faire un echap pour revenir vers le Menu Principal
pointeur de type fiche : p_liste : gràce à ce pointeur on va connaitre la liste chainée
ptr : ce pointeur va servir a parcourir la liste chainée sans toucher à p_liste, notre pointeur de référence pour connaitre la tête de lecture
entiers : fin=0 : si fin passe a 1, on arretera les recherches (fin de liste chainée).
FILE : Repertoire : ce pointeur pointe sur un fichier (Repertoire.txt).
*/
//####################################################################################################

// fonction ecrire_fichier qui écrit dans le repertoire txt ce qu'on a modifiés dans la liste chainée
void ecrire_fichier(fiche *p_liste)
{
int fin=0;
char touche='0';
fiche *ptr=p_liste;; // un pointeur de type fiche qui pointe sur la tete de la liste chainee

FILE* Repertoire = NULL;
Repertoire=fopen("Repertoire.txt","w+"); // si on veut ecrire dans le txt apres avoir tout efface
if(p_liste==NULL)
{
printf("ERREUR : Repertoire vide\n\nECHAP : revenir au Menu du telephone");
fin=1;
}
while(fin==0) // si la liste n'est pas vide
{
if (Repertoire)
{
fprintf(Repertoire,"%s %s %s %s\n",(*ptr).UnContact.numerotel,(*ptr).UnContact.name,(*ptr).UnContact.pren,(*ptr).UnContact.adrmail); // on ?crit
}
else
printf("ERREUR");
if((*ptr).p_suivant==0)
fin=1; //si on est au bout de la liste chainée, il faudra s'arreter
ptr=(*ptr).p_suivant; // le pointeur ptr pointe sur le p_suivant de sa fiche (a la fin il pointera donc sur null)
}
fclose(Repertoire); // on referme le fichier

}
///////////////////////////////////////////////////////////////////////////////////////////////////



//######################################################################################################

/***********************************La fonction trier_1erelettre****************************************

variables: char : touche : l'utilisateur devra faire un echap pour revenir vers le Menu Principal
lettre : c'est un des arguments de la fonction qui correspond à la 1ère lettre du nom tapé par l'utilisateur
chaine : nom_tape : c'est le nom tapé par l'utilisateur.
pointeur de type fiche : p_liste : gràce à ce pointeur on va connaitre la liste chainée
pointeur_de_tri : ce pointeur va servir a parcourir la liste chainée sans toucher à p_liste, notre pointeur de référence pour connaitre la tête de lecture
entiers : presence_contact : compte le nombre de contacts présents dans le répertoire, on renvoie cette variable
nbpassages : pour éviter d'avoir des cls a chaque boucles
fermeture : si fermeture passe a 1, on arretera les recherches (fin de liste chainée).
choix_utilisation : Important : cette fonction a 2 roles : si choix_utilisation=2, on affiche par 1ère lettre si choix_utilisation=5, on affichera par nom entier exacte.
*/
//######################################################################################################

//recherche par premiere lettre (2 cas d'utilisation !!!!!! (cas 1 elle imprime à l'écran les contacts commençant par une lettre choisie, cas 2 elles imprime à l'écran les conatcts commenant par le nom choisit
int trier_1erelettre(fiche *p_liste,char lettre,int choix_utilisation,char *nom_tape)
{
fiche *pointeur_de_tri;
pointeur_de_tri=p_liste; // le pointeur de tri va parcourir la liste, on l'initialise donc par la tete(p_liste)
int presence_contact=0,nbpassages=0,fermeture=0;
char touche='0'; // on initialise par une valeur neutre
if(choix_utilisation==2)
{
system("cls"); // on efface la premiere phrase demandant la lettre tapee par l'utilisateur
printf("----------- liste des contact (1ere lettre) -----------\n\n");
}
else
printf("\n");
while (touche!=27)
{
if (p_liste!=NULL)
{
while(fermeture!=1)
{
if(lettre==*pointeur_de_tri->UnContact.name && choix_utilisation==2)
{
printf("%s %s %s %s\n",(*pointeur_de_tri).UnContact.numerotel,(*pointeur_de_tri).UnContact.name,(*pointeur_de_tri).UnContact.pren,(*pointeur_de_tri).UnContact.adrmail); // on regarde si le nom commence par la lettre sinon on affiche le jeton
presence_contact=1;
}
if((strcmp(nom_tape,pointeur_de_tri->UnContact.name)==0) && choix_utilisation==5) // on regarde si le nom du jeton correspond au nom saisi
{
printf("%s %s %s %s\n",(*pointeur_de_tri).UnContact.numerotel,(*pointeur_de_tri).UnContact.name,(*pointeur_de_tri).UnContact.pren,(*pointeur_de_tri).UnContact.adrmail); // affichage des jetons dont le nom correspond
presence_contact++;
}
if((*pointeur_de_tri).p_suivant!=NULL) // si le pointeur suivant du jeton actuel est different de NULL on change de jeton
pointeur_de_tri=(*pointeur_de_tri).p_suivant;
else // sinon cela signifie que l'on est sur le dernier jeton, on ferme
fermeture=1; // on ferme la boucle quand on arrive a la fin de la liste chainee
}
if (presence_contact==0 && nbpassages==0 && choix_utilisation==2) // ce message doit s'afficher seulement au passage de la 1ere boucle pour eviter une reecriture a chaque passage
printf("ERREUR : Aucuns contacts commencants par %c \n\nECHAP : revenir au Menu du telephone",lettre);
if (presence_contact==1 && nbpassages==0 && choix_utilisation==2) // ce message doit s'afficher seulement au passage de la 1ere boucle pour eviter une reecriture a chaque passage
printf("\nECHAP : revenir au Menu du telephone\n");
}
else
{
if(nbpassages==0 && choix_utilisation==2)
printf("ERREUR, repertoire vide\n\nECHAP : revenir au Menu du telephone");
}
nbpassages++;
if (kbhit())
touche=getch(); // pour sortir de la boucle avec la touche echap (code ascii 27)
if(choix_utilisation==5)
{
touche=27;
printf("\n");
}
}
free(pointeur_de_tri);
return presence_contact;
}
///////////////////////////////////////////////////////////////////////////////////////////////////





//###############################################################################################################

/****************************************La fonction trier_alphabetique*******************************************

variables: chaines : nom,prenom,email,numtel : informations sur le contact
pointeur de type pointeur de type fiche : pp_liste : gràce à ce pointeur on va connaitre la liste chainée
fiche : nouveau : ce pointeur pointera sur le jeton en cours de création
p_parcours : ce pointeur va servir a parcourir la liste chainée sans toucher à p_liste, notre pointeur de référence pour connaitre la tête de lecture. ON va regarder ou sera le bon endroit pour venir insérer
p-courant : maintenant on sait ou insérer, on va le faire gràace a ce pointeur.
FILE : repertoire : ce pointeur pointe sur un fichier (Repertoire.txt).
entiers : compteur : on connait le nombre de jeton qu'on devra parcourir.
i,j : simples variables d'incrémentation
etatlecture: pour connaitre si on se trouve en fin de fichier repertoire ou pas.
position : c'est le numéro du jeton ou on ira insérer.
*/
//################################################################################################################

//fonction tri alphabetique par tri par insertion
void trier_alphabetique (fiche** pp_liste)
{
FILE* repertoire=NULL;
int etatlecture=0,compteur=1,i=0,j=0,position=-1;
char nom[N+1],prenom[N+1],email[M+1],numtel[T+1];
*pp_liste=NULL;
repertoire=fopen("Repertoire.txt","r+");
if(repertoire) // on ouvre le repertoire
{
etatlecture=fscanf(repertoire,"%s%s%s%s",numtel,nom,prenom,email); // 1ere lecture
if (etatlecture!=EOF)
{
fiche* nouveau=(fiche*)malloc(sizeof(fiche)); // si il y a des ecritures dans le fichier on cree le jeton
creation_jeton(nouveau,numtel,nom,prenom,email); // on le remplit
nouveau->p_suivant=*pp_liste; // on lui met l'adresse de pp_liste (NULL)
*pp_liste=nouveau; // puis pp_liste est une liste "chainee" d'un element
}
etatlecture=fscanf(repertoire,"%s%s%s%s",numtel,nom,prenom,email); // 2 ieme lecture
while (etatlecture!=EOF)
{
fiche* nouveau=(fiche*)malloc(sizeof(fiche)); // on cree a nouveau un jeton
creation_jeton(nouveau,numtel,nom,prenom,email); // on entre les donnees
fiche* pcourant=*pp_liste; // on cree deux pointeurs tous deux initialises sur la tete de pp_liste
fiche* p_parcours=*pp_liste;
for(i=0;i<compteur;i++)
{
if(strcmp(p_parcours->UnContact.name,nouveau->UnContact.name)<0) //on "regarde" ou il faudra inserer le nouveau jeton (par exemple sur le 3 ieme parcouru etc)
position=i;
p_parcours=p_parcours->p_suivant; //pour cela nous devons parcourir la liste chainee
}
if (position>=0) // avec le if du desssus, on connais alors la position dans laquelle on doit realiser l'insertion
{
for(j=0;j<position;j++)
pcourant=pcourant->p_suivant; // on recherche la bonne place pour inserer le jeton
nouveau->p_suivant=pcourant->p_suivant; // une fois le jeton trouve, on fait "passer" la liste chainee par notre jeton
pcourant->p_suivant=nouveau;
}
else //sinon c'est deja trie
{
nouveau->p_suivant=*pp_liste;
*pp_liste=nouveau;
}
position=-1;
etatlecture=fscanf(repertoire,"%s%s%s%s",numtel,nom,prenom,email); // prochain passage dans le while
compteur++; // pour compter le nombre de contacts, on pourra faire un return compteur si besoin futur
}
fclose(repertoire);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////




//####################################################################################################

/*********************************La fonction supprimer_contact***************************************

variables: chaines : nom_suppr, prenom_suppr, tel_suppr : informations sur le contact à supprimer
char : touchette : pour que l'utilisateur revienne vers le Menu Principal par echap.
pointeur de type fiche : p_liste : gràce à ce pointeur on va connaitre la liste chainée
p-courant : va parcourir la liste chainée
FILE : Repertoire : ce pointeur pointe sur un fichier (Repertoire.txt).
entiers : fin=0 : si fin passe a 1, on arretera les recherches (fin de liste chainée).
presence_contact : pour connaitre si il y a un contact correspondant à la recherche effectuée
nombre_contact : pour connaitre le nombre de contats portant le nm indiqué par l'utilisateur
*/
//####################################################################################################
void supprimer_contact(fiche *p_liste,char *nom_suppr,char *prenom_suppr,char *tel_suppr,int nombre_contact)
{
int fin=0,presence_contact=0; // initialisations
char touchette='0';
fiche *p_courant=p_liste;
if (p_liste!=NULL) // si le repertoire s'ouvre on marque a la suite de tout ce qui y est marque ce qui nous interesse.
{
FILE* Repertoire = NULL; // il faut ouvrir le fichier: création d'un pointeur de type FILE qui "ouvrira" le fichier
Repertoire=fopen("Repertoire.txt","w+");
if (Repertoire)
{
while (fin==0)
{
if ((strcmp(nom_suppr,(*p_courant).UnContact.name)!=0)&&(nombre_contact==0) || (strcmp(prenom_suppr,(*p_courant).UnContact.pren)!=0)&&(nombre_contact==0) || (strcmp(tel_suppr,(*p_courant).UnContact.numerotel)!=0)&&(nombre_contact==0) || (nombre_contact==1)&&(strcmp(nom_suppr,(*p_courant).UnContact.name)!=0) || (nombre_contact>1)&&(strcmp(tel_suppr,(*p_courant).UnContact.numerotel)!=0)) // si le prenom OU le nom OU le telephone ne sont pas bons (en clair si il existe une différence), il ecrit les autres contacts
fprintf(Repertoire,"%s %s %s %s\n",(*p_courant).UnContact.numerotel,(*p_courant).UnContact.name,(*p_courant).UnContact.pren,(*p_courant).UnContact.adrmail); // on regarde si le nom commence par la lettre et sinon on affiche le jeton
else
presence_contact=1; // sinon on vient de trouver le contact écrit par l'utilisateur
if ((*p_courant).p_suivant!=NULL) // si le pointeur psuivant du jeton actuel est différent de NULL, ça sigifie qu'il y a un jeton derrière
p_courant=(*p_courant).p_suivant; // donc on peut y aller
else
fin=1; // sinon on est a la fin de la liste chainée
}
}
fclose(Repertoire); // on ferme le répertoire
}
system("cls"); // place à l'affichage
if (presence_contact==1)
printf("Contact supprime\n\nECHAP : revenir au Menu du telephone\n");
else
printf("ERREUR : Ce contact n'est pas present dans le repertoire\n\nEchap : Revenir au menu de telephone\n");
while (touchette!=27) // l'utilisateur tapera Echap pour revenir au menu principal
{
if(kbhit())
touchette=getch();
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////




//####################################################################################################

/**********************************La fonction modifier_contact***************************************

variables: chaines : nom_a_modifier, prenom_a_modifier, tel_a_modifier : informations sur le contact à modifier
nom,prenom,adressmail,tel : nouvelles informations sur le contact modifié
char : touche : pour que l'utilisateur revienne vers le Menu Principal par echap.
pointeur de type pointeur de type fiche : pp_liste : gràce à ce pointeur on va connaitre la liste chainée
fiche : pointeur_parcours : va parcourir la liste chainée
entiers : fermeture=0 : si fermeture passe a 1, on arretera les recherches (fin de liste chainée).
presence_contact : pour connaitre si il y a un contact correspondant à la recherche effectuée
r : résultat de l'appel de la fonction contact_deja_present (0 ou 1)
*/
//####################################################################################################
void modifier_contact(fiche **p_liste,char *nom_a_modifier,char *prenom_a_modifier,char *tel_a_modifier,int nombre_contact)
{
fiche *pointeur_parcours=*p_liste; // le pointeur de type fiche qui va parcourir la liste doit etre initialise par la tete
int fermeture=0,r,presence_contact=0;
char nom[N+1],prenom[N+1],adressmail[M+1],tel[T+1],touche='0'; // variables internes a la fonction
system("cls");
if(*p_liste!=NULL)
{
if(nombre_contact==0)
fermeture=1;
while(fermeture!=1)
{
if((nombre_contact>1)&&(strcmp(nom_a_modifier,pointeur_parcours->UnContact.name)==0 && (strcmp(tel_a_modifier,pointeur_parcours->UnContact.numerotel)==0)) || ((nombre_contact==1)&&(strcmp(nom_a_modifier,pointeur_parcours->UnContact.name)==0))) // si le prenom OU le nom ne sont pas bons, il ?crit les autres contacts) // si le nom est pr?sent
{
printf("-------------- Nouvelle Fiche --------------\n\n");
strcpy(nom,verification_donne("nom",N)); // on fait appel a ces fonctions pour s'assurer que l'utilisateur ne va pas entrer des donnees incorrectes
strcpy(prenom,verification_donne("prenom",N));
strcpy(tel,verification_donne("tel",T));
strcpy(adressmail,verification_donne("mail",M));
r=contact_deja_present(tel,p_liste); // on regarde si le telephone n'est pas deja dans la liste chain?e (si deja : 1 sinon 0)
if (r==1)
{
system("cls");
printf("Ce numero existe deja\n\nECHAP : revenir au Menu du telephone");
fermeture=1;
presence_contact=0;
}
else
{
creation_jeton(pointeur_parcours,tel,nom,prenom,adressmail);
fermeture=1;
presence_contact=1;
system("cls");
printf("Contact modifie\n\nECHAP : revenir au Menu du telephone");
}
}
if((*pointeur_parcours).p_suivant!=NULL) // si on est pas sur le dernier jeton on passe au suivant
pointeur_parcours=(*pointeur_parcours).p_suivant;
else
fermeture=1; // sinon on ferme
}
}
if (presence_contact==0)
printf("Erreur ce contact n'existe pas\n\nECHAP : revenir au Menu du telephone");
while(touche!=27)
{
if (kbhit())
touche=getch();
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////




//####################################################################################################

/******************************La fonction demande_suppr_ou_modif*************************************

variables: chaines : pointeur_nom, pointeur_prenom, pointeur_telephone : variable d'entrées de la fonction, qui correspeondent a des emplacement bien caractérisés das la mémoire, il ne sont pas remplis au début de l'appel
pointeur de type fiche : p_liste : gràce à ce pointeur on va connaitre la liste chainée
entiers : fermeture=0 : si fermeture passe a 1, on arretera les recherches (fin de liste chainée).
presence_contact : pour connaitre le nombre de contacts correspondant à la recherche effectuée
*/
//####################################################################################################
int demande_suppr_ou_modif(fiche *p_liste,char *pointeur_nom,char *pointeur_prenom,char *pointeur_telephone,char *role)
{
int presence_contact=0;
system("cls");
printf("------------------%s un contact------------------\n\n",role);
strcpy(pointeur_nom,verification_donne("nom",N)); // on fait appel a ces fonctions pour s'assurer que l'utilisateur ne va pas entrer des donnees incorrectes
trier_alphabetique(&p_liste);
presence_contact=trier_1erelettre(p_liste,pointeur_nom[0],5,pointeur_nom);
if (presence_contact>1) // si plus d'un contact portant ce nom, on demande le prenom
{
strcpy(pointeur_telephone,verification_donne("tel",T)); // on fait appel a ces fonction pour s'assurer que l'utilisateur ne va pas entrer des donnees incorrectes
}
return presence_contact; // on retourne le nombre de contacts.
}
///////////////////////////////////////////////////////////////////////////////////////////////////




//####################################################################################################

/************************************La fonction ajouter**********************************************

variables: chaines : nom, prenom, tel, adressmail : on va écrire les informations dans ces variables seulemnent après avoir été sur que l'utilisateur ne fasse pas bugger le programme
char: touche : pour que l'utilisateur revienne vers le Menu Principal par echap.
pointeur de type pointeur de type fiche : pp_liste : gràce à ce pointeur on va connaitre la liste chainée
fiche : nouveau : pointera sur le jeton qu'on crée.
entiers : fin=0 : si fin passe a 1, on arretera les recherches (fin de liste chainée).
resulatat_appel : résultat de l'appel de la fonction contact_deja_present (0 ou 1)
*/
//####################################################################################################

//fonction ajouter contact qui est utilisee dans le case 3 "ajouter un contact" du main
void ajouter(fiche **pp_liste)
{
char nom[N+1],prenom[N+1],adressmail[M+1],tel[T+1],touche='0'; // variables internes a la fonction
int fin=0,resultat_appel; // pointeur de type fiche (donnee + pointeur)
system("cls"); // affichage
printf("------------------ajouter un contact------------------\n\n");
strcpy(nom,verification_donne("nom",N)); // on fait appel a ces fonctions pour s'assurer que l'utilisateur ne va pas entrer des donnees incorrectes
strcpy(prenom,verification_donne("prenom",N));
strcpy(tel,verification_donne("tel",T));
strcpy(adressmail,verification_donne("mail",M)); // on fait appel a ces fonction pour s'assurer que l'utilisateur ne va pas entrer des donnees incorrectes
resultat_appel=contact_deja_present(tel,pp_liste); // on regarde si le telephone n'est pas deja dans la liste chainee (si deja : 1 sinon 0)
if(resultat_appel==0)
{
fiche* nouveau=(fiche*)malloc(sizeof(fiche)); // si il y a des ecritures dans le fichier on cree le jeton
creation_jeton(nouveau,tel,nom,prenom,adressmail); // on le remplit
nouveau->p_suivant=*pp_liste; // on lui met l'adresse de pp_liste (NULL)
*pp_liste=nouveau; // puis pp_liste est une liste "chainee" d'un element
ecrire_fichier(*pp_liste);
}
system("cls"); // on efface içi,hors de la boucle while de dessous, c'est plus joli
if(resultat_appel==1)
printf("Ce numero existe deja : Contact non ajoute\n\nECHAP : revenir au Menu du telephone");
else
printf("Contact ajoute\n\nECHAP : revenir au Menu du telephone");
while(touche!=27)
{
if(kbhit()) // comme ça avec un Echap on retournera vers le menu principal
touche=getch();
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////




/*######################################################################################################

/****************************************LE MENU PRINCIPAL*********************************************

variables: chaines : nom_a_modifier,nom_a_supprimer,prenom_a_supprimer,prenom_a_modifier,tel_a_modifier,tel_a_supprimer : variables internes a la fonction principales, servant le plus souvent de lien entre les différents appels
char: touche : pour que l'utilisateur revienne vers le Menu Principal par echap.
lettre : lettre tapée par l'utilisateur
pointeur de type fiche : p_liste : gràce à ce pointeur on va connaitre la liste chainée
entiers : fin=0 : si fin passe a 1, on arretera les recherches (fin de liste chainée).
presence_contact : a pour role de passer les arguments d'un appel à l'autre
*/
//####################################################################################################

int main ()
{
system("color F3"); // un peu de couleur, de nos jours tous les téléphone en couleurs voyons !!
int presence_contact=0;
char touche='0',lettre,nom_a_modifier[N+1],nom_a_supprimer[N+1],prenom_a_supprimer[N+1],prenom_a_modifier[N+1],tel_a_modifier[N+1],tel_a_supprimer[N+1];
fiche *p_liste=NULL;
while (touche!=27)
{
system("cls");
touche='0';// on remet touche ='0' à cet endroit juste avant le getch car sinon on ne sortira pas de la boucle !!!
if (kbhit()) // on met dans la variable touche les entrees au clavier de l'utilisateur
touche=getch();
printf("\n --------------- MENU DU TELEPHONE ---------------\n\n\t1> Liste complete des contacts\n\t2> Liste des contacts commencant par...\n\t3> Ajouter un contact\n\t4> Modifier un contact\n\t5> Supprimer un contact\n\t6> Envoyer un SMS\n\t7> Supprimer un SMS\n\t8> Liste des SMS envoyes\n\n\n\tECHAP: Sortir du menu\n");
trier_alphabetique(&p_liste); // on devra toujours trier par ordre alphabetique pour voir si il y a des contacts

switch(touche)
{
case '1' : // afficher la liste complete des contact
{
afficher(p_liste);
}break;

case '2' :
{
system("cls"); // on efface le menu principale et on demande de sasir une lettre
printf("Entrer la premiere lettre : ");
scanf("%c",&lettre);
lettre=toupper(lettre); // on l'a met en majuscule car tous les contacts sont en majuscuels pour éviter de perdre l'utilisateur
trier_1erelettre(p_liste,lettre,2,"nonutile"); // on affiche la liste avec cette 1ère lettre. Attention, la fonction trier 1ère lettre est utilisée dans plusieurs autres cas, le 2 signifie touche=2, ce qui équivaut à afficher la 1ère lettre. On met nonutile car on ne se servira pas de cet argument, mais il faut 4 arguments
}break;

case '3' :
{
ajouter(&p_liste);
}break;

case '4' :
{
presence_contact=demande_suppr_ou_modif(p_liste,nom_a_modifier,prenom_a_modifier,tel_a_modifier,"modifier"); //cette fonction demandera ou nom le téléphone, suivant si le besoin existe (si il n'y a qu'un contact portant le nom saisi par l'utilisateur, le besoin est nul)
modifier_contact(&p_liste,nom_a_modifier,prenom_a_modifier,tel_a_modifier,presence_contact); // au passage on résupère le nombre de contacts. ATTENTION : qui dit passer une question portant sur une indication telle que le téléphone signifie manquer d'information pour trouver le contact dans la liste chianée car si il y a 2 contacts, avec le meme nom et/ou meme prenom, le tel est indispensable, cette fonction saura donc tirer partie des informations dont elle dispose.
ecrire_fichier(p_liste); // bien sur le fichier txt est modifié, on l'efface et on recopie la liste chainée
}break;

case '5' :
{
presence_contact=demande_suppr_ou_modif(p_liste,nom_a_supprimer,prenom_a_supprimer,tel_a_supprimer,"supprimer"); // le principe est le même que "modifier"
supprimer_contact(p_liste,nom_a_supprimer,prenom_a_supprimer,tel_a_supprimer,presence_contact);
trier_alphabetique(&p_liste);
ecrire_fichier(p_liste);
}break;
default : break;
}
fflush(stdin); // pour vider le clavier
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


as d'erreurs au complilateur mais je ne peut pas mettre de noms composés, il zappe la 2ième partie.
bonne chance.
je reviendrait ce soir, je doit partir là.
+++
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
19 avril 2008 à 13:31
Oups,

c'est ma faute
j'ai fait une erreur impardonnable ;-)) ici Message 1

en fait j'ai pensé à fgets
fgets(tampon,taille_recue+1,stdin);
et j'ai melangé tout ;-))

0
Mahmah Messages postés 496 Date d'inscription lundi 17 septembre 2007 Statut Membre Dernière intervention 22 juin 2010 125
19 avril 2008 à 13:41
Salutations,

Je n'ai pas regardé le code, je l'avoue.

Je suis d'accord avec Jeremiethe7 quand à l'utilisation d'un scanf( "%<Taille>s", str ); avec un caractère de plus pour le '\0'
Je désapprouve le fflush( stdin ); (ma raison ici)

Le comportement de scanf %s est de lire une suite de caractères jusqu'à : un espace, une tabulation, un retour chariot ou une fin de fichier. Le problème de la lecture de Jean au lieu de "Jean Paul" n'en est donc pas un. Enfin, ce n'est pas un bug.

Les solutions envisageables sont:
- Interdire la saisie de noms composés. (rien à faire)
- Lire la ligne entière via un fgets( str, <Taille>, stdin ); (et ici pas un gets qui ici ne permet pas de vérifier la taille des données)
- Lire les caractères un à un via fgetc.

Je préconise le fgets aussi, éventuellement avec des sscanf pour analyser la ligne lue mais je ne pense pas que ce soit le cas ici. Attention tout de même. Le retour chariot est lu dans le buffer également. Cela permet de savoir que toute la ligne a été lue lors de cet appel mais on préfèrera l'écraser par un '\0' pour la suite du programme.

M.
0

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

Posez votre question
jerémiethe7 Messages postés 152 Date d'inscription dimanche 2 décembre 2007 Statut Membre Dernière intervention 27 février 2009 32
20 avril 2008 à 09:59
voilà merci pour l'aide.
résolu
0