1. #1
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    août 2013
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : août 2013
    Messages : 20
    Points : 16
    Points
    16

    Par défaut j'ai un probleme avec mon menu il s'affiche en double

    Bonjour

    je rencontre un petit probleme avec mon code :

    si on tape le mot de passe , le menu s'affiche en double , j'aimerai savoir pourquoi

    merci

    Nom : 571599Sanstitre1.jpg
Affichages : 137
Taille : 72,4 Ko

    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    //On appelle les libraires du C
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <string.h>
    //-----------------
     
    //On défini le nombre de caratéres que l'on peux saisir dans notre tableau
    #define S_Produits (15)
    #define S_Quantite (60)
     
    //Structure pour le Nom du produit et sa quantité qu'il ya en stock .
    typedef struct
    {
        char nomProduits[S_Produits+1];
        char nombreProduits[S_Quantite+1];
    } Fiche_Stock;
    //-----------------
     
    //Fonction qui permetant de saisir une chaine enlevant le '\'
    void myGets(char*prompt,char*chaine,unsigned short size )
    {
        char *pt;
        fputs(prompt,stdout);
        fgets(chaine,size,stdin);
        if((pt=strchr(chaine,'\n'))!=NULL)
            *pt='\0';
     
    }
    //Fonction pour  le menu
    unsigned short menu()
    {
        char saisie[100];
        unsigned short choix;
        while(1)
        {
            printf("\t****************** Bienvenu Au Grand Bazar ******************\n\n\n");
            printf("1 : Ouvrir un fichier de stockage\n");
            printf("2 : Ajouter un produit\n");
            printf("3 : Voir le stock \n");
            printf("0 :Quitter\n");
            printf("\nVotre choix : ");
            fflush(stdout);
            fgets(saisie,100,stdin);
            if (sscanf(saisie, "%hu", &choix) == 1 && choix >= 0 && choix <= 3) break;
            printf("Choix incorrect - Recommencez !!!\n");
     
        }
     
        return choix;
     
    }
    //Fonction pour ouvrir un fichier
    FILE *ouvrir_fichier()
    {
        char nom[100];
        char *pt;
        printf("**Ouverture du fichier**\n\n");
        myGets("Saisir un nom pour le fichier: ", nom, 100);
     
        // Vérification extension ".txt" n'existe pas
        if ((pt=strrchr(nom, '.')) == NULL || strcmp(pt, ".txt") != 0)
            strcat(nom,".txt");// on rajoute l'extension .txt au fichier
     
        return fopen(nom, "a+");
    }
    //Fonction pour ajouter un produit à la liste
    void ajouterNom(FILE *fp)
    {
        Fiche_Stock p;
     
        printf("Ajouter nom\n");
        myGets("Entrer un produit :", p.nomProduits, S_Produits);
        myGets("Entrer la quantite :", p.nombreProduits, S_Quantite);
        fprintf(fp, "%s:%s:%s\n", p.nomProduits, p.nombreProduits);
        fflush(fp);
        printf("enregistrement %s:%s:%s ok\n", p.nomProduits, p.nombreProduits);
    }
    //Fonction pour affficher le stock
    void listerNom(FILE *fp)
    {
        Fiche_Stock p;
        long pos;
        char ligne[100];
     
        // Récupération position courante
        pos=ftell(fp);
     
        // Positionnement au début du fichier
        fseek(fp, 0L, SEEK_SET);
     
        // Lecture fichier
        while (fgets(ligne, 100, fp) != NULL)
        {
            printf(ligne);
        }
     
        // Repositionnement à la position initiale du fichier
        fseek(fp, pos, SEEK_SET);
    }
    //Fonction pour afficher le menu
    void afficher_menu()
    {
        FILE *fp=NULL;
        unsigned short choix;
           while((choix=menu()) != 0)
        {
            switch (choix)
            {
                case 1:
                    fp=ouvrir_fichier();
                    if (fp == NULL)
                        fprintf(stderr, "Erreur ouverture fichier\n");
                    break;
                case 2:
                    if (fp == NULL)
                    {
                        fprintf(stderr, "Il faut d'abord ouvrir le fichier\n");
                        break;
                    }
                    ajouterNom(fp);
                    break;
                case 3:
                    if (fp == NULL)
                    {
                        fprintf(stderr, "Il faut d'abord ouvrir le fichier\n");
                        break;
                    }
                    listerNom(fp);
                    break;
                case 0:
                    if (fp != NULL) fclose(fp);
            }
        }
     
         }
     
     
     
     
    //Programme principal
     
    int main()
    {
     
    //Mise en place d'un systeme de mot de passe
        int motpasse =77;
        int code;
     
    do
        {
            printf("veuillez saisir le code : ");
            scanf("%d",&code);
     
            if(code==motpasse)
            {
                system("cls");
                afficher_menu();
     
            }
            else
            {
                printf("Erreur de code !!!");
            }
     
     
     
        }
        while(code !=motpasse);
     
            system("pause");
     
            return 0;
        }

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2005
    Messages
    26 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2005
    Messages : 26 452
    Points : 38 116
    Points
    38 116

    Par défaut

    Le scanf("%d", &code) laisse le '\n' dans le buffer clavier.
    Il faut finir de lire la ligne après chaque scanf(). Pour ça, j'utilise une fonction du forum qu'on tend à appeler fpurge().

    Voici ton code avec les fonctions ajoutées, et des commentaires de ma part:
    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    /*On inclut les en-têtes de la bibliothèque standard du C*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    /*On inclut les en-têtes non-standard*/
    /*#include <conio.h>*/ /*Je n'ai rien vu dans le code qui utilisait conio*/
    /*-----------------*/
     
    //On défini le nombre de caratéres que l'on peux saisir dans notre tableau
    #define S_Produits (15)
    #define S_Quantite (60)
     
    //Structure pour le Nom du produit et sa quantité qu'il ya en stock .
    typedef struct
    {
    	char nomProduits[S_Produits+1];
    	char nombreProduits[S_Quantite+1];
    } Fiche_Stock;
    /*-----------------*/
     
    /*Returns 0 if OK, a negative value if EOF.*/
    int fpurge(FILE *f)
    {
    	int c;
    	while((c=fgetc(f))!=EOF && c!='\n')
    	{ }
    	return (c==EOF ? -1 : 0);
    }
     
    /* Returns a nonzero value if found, zero if not. */
    int truncate_newline(char *str)
    {
    	int bRet=0;
    	if(str!=NULL)
    	{
    		char *pNewline = strchr(str, '\n');
    		if(pNewLine!=NULL)
    		{
    			bRet = 1;
    			*pNewLine = '\0';
    		}
    	}
    	return bRet;
    }
     
    /* Returns 0 if buffer is full, a positive value if line is complete,
       a negative value if EOF (implies buffer full). */
    int fclean(char *str, FILE *f)
    {
    	int ret = 1;
    	if(!truncate_newline(str))
    		ret = fpurge(f);
    	return ret;
    }
     
    /*Fonction qui permetant de saisir une chaine enlevant le '\n'*/
    void myGets(char const *prompt, char* chaine, size_t size )
    {
    	fputs(prompt, stdout);
    	fgets(chaine, size, stdin);
    	fclean(chaine, stdin);
    }
     
    /*Fonction pour  le menu*/
    unsigned short menu()
    {
    	char saisie[100];
    	unsigned short choix;
    	while(1)
    	{
    		printf("\t****************** Bienvenu Au Grand Bazar ******************\n\n\n");
    		printf("1 : Ouvrir un fichier de stockage\n");
    		printf("2 : Ajouter un produit\n");
    		printf("3 : Voir le stock \n");
    		printf("0 :Quitter\n");
    		printf("\nVotre choix : ");
    		fflush(stdout);
    		myGets(saisie,100,stdin);
    		if (sscanf(saisie, "%hu", &choix) == 1 && choix >= 0 && choix <= 3) break;
    		printf("Choix incorrect - Recommencez !!!\n");
    	}
     
    	return choix;
    }
     
    /*Fonction pour ouvrir un fichier */
    FILE *ouvrir_fichier()
    {
    	char nom[100+4]; /*Nom de fichier + extension .txt qu'on rajoute. */
    	char *pt;
    	printf("**Ouverture du fichier**\n\n");
    	myGets("Saisir un nom pour le fichier: ", nom, 100);
     
    	/* Ajouter extension ".txt" si elle n'est pas précisée */
    	if ((pt=strrchr(nom, '.')) == NULL || strcmp(pt, ".txt") != 0)
    		strcat(nom,".txt");/* on rajoute l'extension .txt au fichier*/
     
    	return fopen(nom, "a+");
    }
     
    /*Fonction pour ajouter un produit à la liste*/
    void ajouterNom(FILE *fp)
    {
    	Fiche_Stock prod; /*Laissons le nom 'p' aux pointeurs*/
     
    	printf("Ajouter nom\n");
    	myGets("Entrer un produit :", prod.nomProduits, S_Produits);
    	myGets("Entrer la quantite :", prod.nombreProduits, S_Quantite);
    	fprintf(fp, "%s:%s\n", prod.nomProduits, prod.nombreProduits); /*Attention il y avait un %s de trop*/
    	fflush(fp);
    	printf("enregistrement %s:%s ok\n", p.nomProduits, p.nombreProduits); /*Attention il y avait un %s de trop*/
    }
     
    /*Fonction pour affficher le stock*/
    void listerNom(FILE *fp)
    {
    	Fiche_Stock p;
    	long pos;
    	char ligne[100];
     
    	/* Récupération position courante */
    	pos=ftell(fp);
     
    	/* Positionnement au début du fichier */
    	fseek(fp, 0L, SEEK_SET);
     
    	/* Lecture fichier */
    	while (fgets(ligne, 100, fp) != NULL)
    	{
    		printf(ligne);
    	}
     
    	/* Repositionnement à la position initiale du fichier */
    	fseek(fp, pos, SEEK_SET);
    }
     
    /*Fonction pour afficher le menu*/
    void afficher_menu()
    {
    	FILE *fp=NULL;
    	unsigned short choix;
     
    	while((choix=menu()) != 0)
    	{
    		switch (choix)
    		{
    		case 1:
    			if(fp != NULL) fclose(fp); /*Il faut fermer le fichier s'il est déjà ouvert*/
    			fp=ouvrir_fichier();
    			if (fp == NULL)
    				fprintf(stderr, "Erreur ouverture fichier\n");
    			break;
    		case 2:
    			if (fp == NULL)
    			{
    				fprintf(stderr, "Il faut d'abord ouvrir le fichier\n");
    				break;
    			}
    			ajouterNom(fp);
    			break;
    		case 3:
    			if (fp == NULL)
    			{
    				fprintf(stderr, "Il faut d'abord ouvrir le fichier\n");
    				break;
    			}
    			listerNom(fp);
    			break;
    		}
    	}
    	/*À cause du while, le case 0 n'était jamais exécuté, je l'ai donc sorti du while*/
    	if (fp != NULL) fclose(fp);
    	fp = NULL; /*On remet à NULL après avoir fermé*/
    }
     
     
     
     
    /*Programme principal*/
     
    int main()
    {
    	/*Mise en place d'un systeme de mot de passe*/
    	int motpasse =77;
    	int code;
    	int nScan; /*Je rajoute cette variable pour tester le retour de scanf*/
     
    	do
    	{
    		printf("veuillez saisir le code : ");
    		nScan = scanf("%d",&code);
    		fpurge(stdin); /*On lit le \n et tout ce qui a été saisi derrière*/
     
    		if(nScan==1 && code==motpasse) /*Ainsi on ne fera pas la comparaison si code n'est pas initialisé*/
    		{
    			system("cls");
    			afficher_menu();
    		}
    		else
    		{
    			printf("Erreur de code !!!");
    		}
     
    	}
    	while(nScan != EOF && (nScan!=1 || code !=motpasse));
    	/*Le test de EOF permet de quitter complètement le programme si l'utilisateur ferme le flux d'entrée.*/
    	/*Le test de 1 permet de ne pas comparer le mot de passe tant que l'utilisateur n'en aura pas saisi un valide.*/
     
    	system("pause");
     
    	return 0;
    }
    Dans l'ensemble, ton code m'a l'air assez solide. Il me rappelle mes premiers codes C.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    août 2013
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : août 2013
    Messages : 20
    Points : 16
    Points
    16

    Par défaut

    merci de ta réponse si j'ai bien compris il faut vider le buffer

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2005
    Messages
    26 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2005
    Messages : 26 452
    Points : 38 116
    Points
    38 116

    Par défaut

    Oui:
    • Systématiquement après un scanf
    • Après un fgets() si la saisie était plus grande que le buffer (ce que fclean() détecte en utilisant strchr() comme tu le faisais)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Lycéen
    Inscrit en
    août 2013
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : août 2013
    Messages : 20
    Points : 16
    Points
    16

    Par défaut

    j'ai pensé à mettre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while(getchar() != '\n');

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2005
    Messages
    26 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2005
    Messages : 26 452
    Points : 38 116
    Points
    38 116

    Par défaut

    Fais gaffe, tu devrais aussi tester EOF (comme on le fait dans fpurge()), sinon tu risques une boucle infinie.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    5 831
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    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 : 5 831
    Points : 16 032
    Points
    16 032
    Billets dans le blog
    1

    Par défaut

    Citation Envoyé par marcous Voir le message
    merci de ta réponse si j'ai bien compris il faut vider le buffer
    Bonjour

    Personnellement je n'aime pas purger le buffer parce que cela peut supprimer des informations importantes. Par exemple je ne sais pas comment se comporterait un tel code si (dans un système Unix) on le plaçait en sortie de pipe.

    Perso je préfère utiliser la technologie fgets() + sscanf() qui récupère et analyse tout le buffer plutôt que d'effacer son contenu. C'est d'ailleurs ce que tu fais dans ton menu. Faut juste l'appliquer à toutes les autres saisies...
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2005
    Messages
    26 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2005
    Messages : 26 452
    Points : 38 116
    Points
    38 116

    Par défaut

    Citation Envoyé par Sve@r Voir le message
    Personnellement je n'aime pas purger le buffer parce que cela peut supprimer des informations importantes. Par exemple je ne sais pas comment se comporterait un tel code si (dans un système Unix) on le plaçait en sortie de pipe.
    C'est très simple, il ignorerait le restant de la ligne et commencerait sa prochaine saisie (càd, son prochain fgets()) à la ligne suivante.

    À défaut d'accepter des données de longueur arbitraire (ce à quoi fgets()+sscanf() ne suffit pas de toute façon, il faut un truc du genre getline() pour ça), il vaut mieux ignorer l'excédent de données plutôt que le laisser décaler toutes les saisies futures.


    Edit: Il y a toujours un point sur lequel fgets()+sscanf() est supérieur à scanf(): Si l'on saisit une ligne vide, scanf() l'ignore, tandis que fgets()+sscanf() repérera qu'une ligne vide a été saisie. Résultat, si on place le code en sortie de pipe, avec scanf() seul on aura droit à un décalage d'une ou plusieurs lignes dans l'autre sens.

    Pour cette raison, on peut avoir une bonne raison de bannir scanf() au profit de fgets()+sscanf().
    Enfin, plus précisement, fgets() + fclean() + sscanf() ou bien getline() + sscanf().
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

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

Discussions similaires

  1. probleme avec mon menu
    Par Invité dans le forum Débuter
    Réponses: 14
    Dernier message: 07/07/2013, 10h01
  2. Probleme avec mon menu (vertical) CSS
    Par charleshbo dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 10/06/2008, 16h53
  3. [CSS] Probleme avec mon menu css
    Par otagun dans le forum Mise en page CSS
    Réponses: 7
    Dernier message: 13/05/2006, 14h37
  4. Probleme avec mon professeur
    Par Hamza dans le forum Général Algorithmique
    Réponses: 20
    Dernier message: 16/07/2005, 10h50
  5. [Thread] Probleme avec mon Timer
    Par Nico66 dans le forum EDT/SwingWorker
    Réponses: 10
    Dernier message: 02/06/2005, 17h10

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