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

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

C Discussion :

probleme exercice 'bulletin'


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2024
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 21
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2024
    Messages : 6
    Par défaut probleme exercice 'bulletin'
    Bonsoir,

    Je me permet de vous poser une question concernant mon code dont l'objectif est de saisir pour un certain nombre d'étudiant, leurs nom et prénom ainsi que 3 notes. Le programme a la fin affiche les coordonnées de chaque étudiant avec leurs nom, prénom, leurs notes et la moyenne.
    Or je viens débuter il y a peu en C et je ne comprend pas du tout où se trouve le problème dans la saisie de mes coordonnées ....le programme ne me laisse pas saisir le nom du premier étudiant. De plus lors de l'affichage, le nom et prénom de l'étudiant s'affiche mal sans que je n'arrive à comprendre mon erreur.

    Merci d'avance pour l'aide que vous pourrez m'apporter.

    Bonne soirée à vous.

    voici mon programme :
    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
     
    #include <stdio.h>
    #define nmax 30
     
     
    //-----------------------
    // Fonction saisir le nombre d'étudiant
    //-----------------------
    int saisir_nombre_etudiant()
    {
        int a ;
      do{
        printf(" donner un nombre entre 1 et %d:",nmax );
        scanf("%d",&a);
     }while(a<=0 || a>=nmax );
        return(a);
    }
    //-----------------------
    // procédure saisir coordonnées
    //-----------------------
    void saisir_coordonnes(int a, char nom[a][30], char prenom[a][30], char id[a][61])
    {
        int i;
        for (i = 0; i < a; i++) {
            printf("\nNom : ");
            gets(nom[i]);
     
            printf("\nPrenom : ");
            gets(prenom[i]);
            strcpy(id[i] , prenom[i] ) ;
            strcat(id[i] , " " );
            strcat(id[i], nom[i]);
    }}
    //-----------------------
    // procédure saisir notes
    //-----------------------
    void saisir_notes ( int note1[nmax], int note2[nmax], int note3[nmax],int a)
       {
     
        int i;
        for (i=0; i<a; i++)
        {
         printf("\n saisir les notes de l'etudiant %d :", i+1);
         printf("\nnote 1 :");
         scanf("%d",&note1[i]);
     
         printf("\nnote 2 :");
         scanf("%d",&note2[i]);
     
         printf("\nnote 3 :");
         scanf("%d",&note3[i]);
        }
     
       }
    //-----------------------
    // procédure moyenne
    //-----------------------
     
    void moyenne_tableau (int note1[nmax],int note2[nmax],int note3[nmax], int a ,float moy[nmax])
    {
        int i;
        for ( i=0; i<a ; i++)
            moy[i]=((float)note1[i]+(float)note2[i]+(float)note3[i])/3;
     
    }
     
    //-----------------------
    // Procedure afficher tableau
    //-----------------------
    void afficher_tableau (int note1[nmax],int note2[nmax], int note3[nmax],int a,float moy[nmax], char id[a][30] )
    {
        int i ;
        printf("\nLes relevé de notes des éleves :\n : ");
        for ( i=0; i<a; i++)
        {
            printf("\n----------------------");
            printf(" \netudiant n°%d : %s ",i+1,id[i]);
            printf("\n----------------------");
     
            printf("\nnote 1 : %d",note1[i]);
            printf("\nnote 2 : %d",note2[i]);
            printf("\nnote 3 : %d",note3[i]);
            printf("\n----------------------");
            printf(" \nmoyenne :%f ", moy[i]);
     
        }
     
    }
    main(){
    int note1[nmax],note2[nmax],note3[nmax],a;
    float moy[nmax];
    char nom[a][30] ,prenom[a][30],id[a][61];
    a=saisir_nombre_etudiant();
    saisir_coordonnes(a, nom, prenom,id);
     
    saisir_notes(note1, note2, note3, a);
     
    moyenne_tableau(note1, note2, note3, a, moy);
     
    afficher_tableau(note1, note2, note3, a, moy, id);
     
    }

  2. #2
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 784
    Par défaut
    Hello,

    Ligne 92, tu déclares des tableaux de type vla avec la variable 'a'. Oui, pourquoi pas, mais cette variable 'a' n'est initialisée qu'à la ligne suivante....
    Je n'ai pas été plus loin.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2024
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 21
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2024
    Messages : 6
    Par défaut
    Merci beaucoup pour ta réponse aussi rapide, effectivement je n'avais pas fait attention à ce détail mais il ne semblait pas avoir d'impact sur le code après modification ( et je ne sais pas pourquoi le programme fonctionnait quand même alors qu'il n'avais pas la valeur de a ).

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 833
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

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

    Informations forums :
    Inscription : Février 2006
    Messages : 12 833
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Hgo-Crltt Voir le message
    ( et je ne sais pas pourquoi le programme fonctionnait quand même alors qu'il n'avais pas la valeur de a ).
    Comportement indéterminé (UB en anglais). C'est le pire cas possible en C car indétectable.
    Le C est un langage fait pour aller vite donc il ne vérifie rien de ce que tu écris. Soit tu respectes ses obligations et tout va bien, soit tu ne les respectes pas et il exécute tes instructions quelles qu'elles soient et là ça peut fonctionner ou ne pas fonctionner. Ou fonctionner une semaine puis tu rajoutes un truc banal et ça ne fonctionne plus (et là va chercher la cause du souci qui n'est pas dans le rajout mais dans l'erreur précédente !!!)
    Dans l'absolu ça peut même t'envoyer un écran bleu ou éteindre ta machine. C'est la définition parfaite de "indéterminé" => qui ne peut pas être prévu.
    Dans le cas présent, tu ne peux pas dire que "a" n'a pas de valeur car une variable a toujours une valeur. Donc ça crée bien un tableau de "a" éléments.

    Sinon pour le souci principal (à savoir la "non-saisie" du nom) cela vient de la saisie précédente (le scanf dans la fonction "saisir_nombre_etudiant"). Quand tu entres ton nombre, tu valide par <return>. Le scanf() récupère donc le nombre (normal) et laisse le <return> qui n'est pas un nombre dans le clavier (normal aussi). Ensuite à la saisie suivante le gets (saisie chaine) fait son travail et récupère la chaine toujours présente dans le clavier (le <return>). Tout est cohérent.

    Je ne sais pas qui t'a appris le C mais il est clair que lui-même n'y connait rien en C. Dans l'immédiat, si tu veux voir ton code tourner, rajoute getchar() juste sous le scanf() de la ligne 16. C'est juste un pansement sommaire qui permet de récupérer dans le vide (donc de virer) le <return>. Plus tard tu apprendras à faire de la saisie propre donc sans passer par scanf() qui n'est pas faite pour ça (mais fatalement on la montre immédiatement car elle permet de commencer des exercices).

    Ensuite pour avoir un code un peu plus propre, alors
    • remplace gets(nom[i]) par fgets(nom[i], 30+1, stdin) (et pareil au prénom)
    • soit cohérent avec id[] définit à 61 dans le main() et à 30 dans saisir_coordonnees()
    • rajoute son type int à la fonction main()
    • n'utilise pas de VLA (les tableaux avec une variable en taille) car c'est non protégé (si ça plante tu ne le sais pas et UB). Puisque tu as nmax élèves alors tu crées un tableau à nmax. Plus tard tu apprendras à demander à l'OS de la mémoire si tu veux créer des tableaux vraiment variables et là tu pourras gérer si l'OS ne peut pas répondre à ta demande.
    • mets tes macros (nmax) en majuscules
    • indente correctement. Ca montrera que tu es heureux et fier d'écrire ce programme qui te permet d'imposer des calculs et traitements de ton choix à cette machine stupide et que le C n'est pas pour toi qu'une corvée à expédier avant de retourner jouer à COD. Ou, à défaut de respecter ton code, ça montrera au-moins que tu respectes ceux à qui tu demandes de le lire


    Pour l'élégance tu peux remplacer tes strcat() à répétition par sprintf(id[i], "%s %s", prenom[i], nom[i]) et moy[i]=((float)note1[i]+(float)note2[i]+(float)note3[i])/3 par moy[i]=(note1[i] + note2[i] + note3[i]) / 3.0 (un seul float suffit pour avoir la division en float et aérer son code ne fait pas de mal). Accessoirement moi j'aurais fait des fonctions permettant de gérer "un" étudiant et je les aurais appelées pour chaque étudiant (c'est plus souple donc plus réutilisable).

    Et fais attention aux tableaux 2D car en C, dès qu'on dépasse 1D il faut être super rigoureux. Hélas une chaine étant déjà un tableau, vouloir rien qu'un tableau de strings c'est déjà de la 2D.
    Mon Tutoriel sur la programmation «Python»
    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
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2024
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 21
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2024
    Messages : 6
    Par défaut
    Bonjour Sve@r

    Tout d'abord, merci énormément pour votre réponse, cela m'a bien aidé. Votre idée du getchar() a bien fonctionné mais un problème que je ne saurais expliquer ( votre expérience le saura peut être) est toujours présent : pourquoi lors de l'exécution du programme et plus particulièrement lors de l'affichage du tableau, seul le nom d'un étudiant sur 2 apparait ( je ne vois pas d'erreur dans la boucle for ou dans la saisie de ID). Dans mon exemple j'ai pris 4 étudiants ( Claude Francois, Jean Schultheis, Gilbert Montagné et Johnny Hallyday), vous trouverez ci-joint l'affichage du tableau en sortie.

    Merci aussi pour les conseils qui vont permettre une meilleure visibilité du code

    Par ailleurs auriez vous des conseils afin d'éviter à l'avenir les comportements indéterminés ? ( des fautes types, une règle de base a connaitre….)

    Merci d'avance

    Bonne journée et bon Dimanche
    Images attachées Images attachées  

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

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

    Informations forums :
    Inscription : Février 2006
    Messages : 12 833
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Hgo-Crltt Voir le message
    Votre idée du getchar() a bien fonctionné
    C'est pas "mon" idée, le truc est assez connu. Et attention, c'est juste une rustine. Tape "5xxxxxxx" à la saisie du nb et ça ne fonctionne plus (le getchar() ne supprime qu'un seul caractère).

    Citation Envoyé par Hgo-Crltt Voir le message
    pourquoi lors de l'exécution du programme et plus particulièrement lors de l'affichage du tableau, seul le nom d'un étudiant sur 2 apparait ( je ne vois pas d'erreur dans la boucle for ou dans la saisie de ID). Dans mon exemple j'ai pris 4 étudiants ( Claude Francois, Jean Schultheis, Gilbert Montagné et Johnny Hallyday), vous trouverez ci-joint l'affichage du tableau en sortie.
    Alors ton code rectifié chez-moi (le getchar(), remplacer gets() par fgets()) fonctionne correctement. As-tu pensé au fgets() ?
    Dans ta copie d'écran je vois un "°" devant "Jean". J'ai l'impression que lors de la saisie, il enregistre des trucs en plus ce qui reproduit le même phénomène (la saisie suivante récupère le truc en plus de la saisie précédente) et si ça marche chez-moi c'est que je suis sous Linux (OS écrit en C donc dans lequel le C lui est implicitement lié). Toi tu sembles bosser sous Windows pour qui le C n'est qu'une verrue qu'il tolère à peine et où ses compilateurs ont été écrits avec les pieds. Mais si tu as bien corrigé alors reposte le nouveau code.

    Citation Envoyé par Hgo-Crltt Voir le message
    Par ailleurs auriez vous des conseils afin d'éviter à l'avenir les comportements indéterminés ? ( des fautes types, une règle de base a connaitre….)
    Désolé, si on avait un truc pour l'éviter ce ne serait pas la terreur des devs C. Ton cerveau est la meilleurs arme (utiliser "a" avant de le remplir...)
    Mon Tutoriel sur la programmation «Python»
    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
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. Problème exercice facile
    Par arnaud405 dans le forum Caml
    Réponses: 17
    Dernier message: 04/10/2007, 22h30
  2. Problème Exercice Débutant
    Par nanoute dans le forum C
    Réponses: 34
    Dernier message: 19/05/2007, 17h14
  3. probleme exercice C++
    Par ludo86 dans le forum C++
    Réponses: 9
    Dernier message: 09/04/2007, 15h00
  4. Probleme exercice list
    Par Gebudi. dans le forum C++
    Réponses: 6
    Dernier message: 31/07/2006, 15h43
  5. problemes exercices sql
    Par siciliano_messinese dans le forum Langage SQL
    Réponses: 3
    Dernier message: 23/09/2005, 16h52

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