Aide pour trouver une erreur sur un programme

viktorfrankestein Messages postés 13 Statut Membre -  
viktorfrankestein Messages postés 13 Statut Membre -
Bonjour a tous s'il vous plait aidez moi à comprendre l'erreur dans le code suivant.

 En fait le programme est divisé en 5parties. s'il vous plait: prenez le temps de l 'executer avec les indications que je vais donner sinon vous risquez de ne pas comprendre mon problème parce qu'il compile mais ne fait pas ce que je veux.

Que fait le programme?

le programme en question demande à un utilisateur de donner un nombre de matiere (par exemple en classe maths physique chimie etc... )

puis vous devez entrer ces matières selon l'ordre qu'il vous plaira ensuite vous devez entrer le coefficient des matières dans l'ordre des matières et la note aussi.

le coefficient en question doit etre compris entre 0 et 7 (donc 1 jusqu'à 6) et la note de 0 à 20. si vous débordez c'est là qu'il y 'a problème. le programme que j'ai écrit pour regler ça ne fonctionne pas bien. donc s'il vous plait tester d'abord dans les normes puis dans les erreurs pour bien voir la différence.

le code a été écrit avec code block sur Windows

VOICI LE MAIN

#include <vector>
#include"unitedecontrole.h"
using namespace std;
int main()
{
    // creation des vecteurs recuperateurs
    vector<string> matieres;
    int nbreMatiere;
    vector<int> coef;
    vector<int> note;
    cout << " veuillez entrer le nombre de matiere" << endl;
    cin >> nbreMatiere;
    matieres = matiere(nbreMatiere);
    coef = coefficient(nbreMatiere);
    note = noteMatieres(nbreMatiere);
    return 0;
}

VOICI LE 1er FICHIER SOURCE : fonctionpourlesmoyennes.cpp (il contient toutes fonctions pour faire les demandes)

#include"fonctionspourlesmoyennes.h"
#include<vector>
#include<string>
#include<iostream>
#include"unitedecontrole.h"
using namespace std;

// fontion pour la demande des matières

vector<string> matiere ( int nbreMatiere)
{
    string uneMatiere("maths");// variable pour le nom d une matiere
    vector<string> matieres;// tableau dynamique contenant qui va contenir toutes les matieres
    cout << "veuillez entrer vos matiere" << endl;
    for(int i(0);i<nbreMatiere;i++)
    {
        cin.ignore();// reinitialisation de la fonction cin
        getline(cin, uneMatiere); // recuperation de la variable cin
        matieres.push_back(uneMatiere); // ajout au tableau
    }
    return matieres; // retour du tableau dynamique
}

// fonction pour la demande des coefficients

vector<int> coefficient (int nbreCoef)
{
    bool controlleur(false); // variable qui controlle si le user a entre les bons chiffres

    int const grandCoef(6); // le coefficient max que peut avoir une matiere

    vector<int> coef; // tableau contenant les coefficient////

    int unCoef(0);

    cout << "veuillez entrer vos coefficients dans l ordre des matieres" << endl;

    for(int j(0);j<nbreCoef;j++)// demande des coef a le user et verification de la valeur entré
    {
        cin >> unCoef;

        coef.push_back(unCoef);

        controlleur=controlle(coef, j, grandCoef); // reception du resultat de la verification de la valeur entree

        if(controlleur)
            coefficient(nbreCoef);// on recomence au debut au cas ou la valeur est fausse
    }
    return coef; // retour du tableauu des coefficient
}
vector<int> noteMatieres (int nbreNote)
{
    vector<int> note;

    int uneNote(0);

    cout << "veuillez entrer vos notes dans l ordre des matieres" << endl;

    for(int k(0);k<nbreNote;k++)
    {
        int const grdeNote(20);

        cin >> uneNote;

        note.push_back(uneNote);

        bool controlleur(controlle(note, k, grdeNote));

        if(controlleur)
            noteMatieres(nbreNote);
    }
    return note;

}
 
VOICI LE 2eme FICHIER SOURCE : unitedecontrolle.cpp (il contient la fonction qui va faire le controlle des valeurs des coefficients et notes entrées )

#include"unitedecontrole.h"
#include"fonctionspourlesmoyennes.h"
#include<iostream>
using namespace std;

bool controlle(vector<int> coef, int compteur, int const randCoef)

{
    if (coef[compteur]<=0 || coef[compteur]>randCoef)

    {
        for(int t(compteur);t>=0;t--)
        coef.pop_back();

    cout << "Erreur!!! " << endl << endl;

    cout << "vous allez recommencez depuis le debut " << endl << endl;

    return true;
    }
    else
        return false;
}
VOICI LE 1er HEADER
#ifndef UNITEDECONTROLE_H_INCLUDED
#define UNITEDECONTROLE_H_INCLUDED
#include<vector>
#include<iostream>
using namespace std;

bool controlle(vector<int> coef, int compteur, int const randCoef);

#endif // UNITEDECONTROLE_H_INCLUDED

VOICI LE 2eme HEADER

#ifndef UNITEDECONTROLE_H_INCLUDED
#define UNITEDECONTROLE_H_INCLUDED
#include<vector>
#include<iostream>
using namespace std;

bool controlle(vector<int> coef, int compteur, int const randCoef);

#endif // UNITEDECONTROLE_H_INCLUDED

Je vous remercie deja pour l'aide.

3 réponses

  1. viktorfrankestein Messages postés 13 Statut Membre
     
    apres avoir relu les regles du forum voici en fait mon probleme.

    fonction pour la demande des coefficients

    vector<int> coefficient (int nbreCoef)
    {
        bool controlleur(false); // variable qui controlle si le user a entre les bons chiffres

        int const grandCoef(6); // le coefficient max que peut avoir une matiere

        vector<int> coef; // tableau contenant les coefficient

        int unCoef(0);

        cout << "veuillez entrer vos coefficients dans l ordre des matieres" << endl;

        for(int j(0);j<nbreCoef;j++) // demande des coef a le user et verification de la valeur entré
        {
            cin >> unCoef;

            coef.push_back(unCoef);

            controlleur=controlle(coef, j, grandCoef); // reception du resultat de la verification de la valeur entree

            if(controlleur)
                coefficient(nbreCoef);// on recomence au debut au cas ou la valeur est fausse
        }
        int tailletab(coef.size());

        cout << "la taille du tab est " << tailletab << endl;

        return coef; // retour du tableauu des coefficient

    }

    la fonction qui va faire le controlle des valeurs des coefficients et notes entrées
    bool controlle(vector<int> coef, int compteur, int const randCoef)
    {
        if (coef[compteur]<=0 || coef[compteur]>randCoef)
        {
            for(int t(compteur);t>=0;t--)

            coef.pop_back();

        cout << "Erreur!!! " << endl << endl;

        cout << "vous allez recommencez depuis le debut " << endl << endl;

        return true;
        }

        else
            return false;
    }
    voici par exemple le resultat d'un code qui marche
     
    veuillez entrer le nombre de matiere
    3
    veuillez entrer vos matiere
    maths
    physique
    chimie
    veuillez entrer vos coefficients dans l ordre des matieres
    6
    4
    5
    la taille du tab est 3
    veuillez entrer vos notes dans l ordre des matieres
    12
    13
    14
    Process returned 0 (0x0)   execution time : 57.258 s
    Press any key to continue.

    voici le resultat de quand ça ne marche pas quand le mauvais coefficient est entrée dans coef[j] où j est egale à 0


     veuillez entrer le nombre de matiere
    3
    veuillez entrer vos matiere
    maths
    physique
    chimie
    veuillez entrer vos coefficients dans l ordre des matieres
    7
    Erreur!!!
    vous allez recommencez depuis le debut
    veuillez entrer vos coefficients dans l ordre des matieres
    6
    5
    4
    la taille du tab est 3
    5
    4
    la taille du tab est 3
    veuillez entrer vos notes dans l ordre des matieres
    12
    15
    16
    Process returned 0 (0x0)   execution time : 60.570 s
    Press any key to continue.

    les trois lignes en gras je ne comprend pas leur apparition.

    Après quelques tests j'ai remarqué que

    si j'entre une érreur à la position J de mon tableau coef alors le programme execute ma fonction bool controlle(vector<int> coef, int compteur, int const randCoef) 

    puis le programme recommence à redemander les coefficients et les stocke a partir de coef[J==0]

     mais il me demande en plus (nbreCoef -(J + 1)) qu'il va stocker dans le tableau coef à coef[j] puis coef[j++] ainsi de suite jusqu à J=nbreCoef
    (mais cette fois j est egale à au numéro où l'erreur a été trouvé et je ne sais pas comment) 

    voici une illustration quand le mauvais coefficient est entrée dans coef[j] où j est egale à 1

    veuillez entrer le nombre de matiere
    3
    veuillez entrer vos matiere
    maths
    physique
    chimie
    veuillez entrer vos coefficients dans l ordre des matieres
    6
    7
    Erreur!!!
    vous allez recommencez depuis le debut
    veuillez entrer vos coefficients dans l ordre des matieres
    6
    5
    4
    la taille du tab est 3
    4
    la taille du tab est 3
    veuillez entrer vos notes dans l ordre des matieres
    12
    15
    14
    Process returned 0 (0x0)   execution time : 68.628 s
    Press any key to continue.

    je note dans ce qui précede que on a eu droit que a une seule demande en plus.
    c'est à dire nbreCoef(qui est 3 dans notre cas ) - (J+1) j c'est 1 dans ce cas donc on a 3 - (1+1)=1 donc seule a été faite en plus 

    je vous remercie de bien vouloir m'aider
    0
    1. viktorfrankestein Messages postés 13 Statut Membre
       
      voici un autre test que j'ai fait pour trouver mon érreur

      voici la modification de la boucle for de la fonction coefficient

      for(int j(0);j<nbreCoef;j++)
      {
      cin >> unCoef;
      coef.push_back(unCoef);
      cout << "test de j" <<endl;
      controlleur=controlle(coef, j, grandCoef);
      cout << "la val avant la verification de controlleur j est" << j << endl;
      if(controlleur)
      {
      cout << "la val apres la verifiation de controlleur j est" << j << endl;
      coefficient(nbreCoef);
      }
      else
      cout << "test" << endl;
      }
      int tailletab(coef.size());
      cout << "la taille du tab est " << tailletab << endl;
      return coef;
      }


      et voici le resultat de l'execution




      veuillez entrer le nombre de matiere
      3
      veuillez entrer vos matiere
      maths
      physique
      chimie
      veuillez entrer vos coefficients dans l ordre des matieres
      7
      test de j
      Erreur!!!

      vous allez recommencez depuis le debut

      la val avant de la boucle j est0
      la val apres de j est0
      veuillez entrer vos coefficients dans l ordre des matieres
      6
      test de j
      la val avant de j est0
      test
      5
      test de j
      la val avant de j est1
      test
      4
      test de j
      la val avant de j est2
      test
      la taille du tab est 3
      5
      test de j
      la val avant de j est1
      test
      4
      test de j
      la val avant de j est2
      test
      la taille du tab est 3
      veuillez entrer vos notes dans l ordre des matieres
      12
      12
      12

      Process returned 0 (0x0) execution time : 101.140 s
      Press any key to continue.
      0
    2. viktorfrankestein Messages postés 13 Statut Membre
       
      si tu regardes bien tu verras que la fontion s'exécute jusquà sortir de la boucle for (parce qu'elle affiche deja la taille du tableau ) puis elle rentre dans le boucle for et c ' est là que je suis perdu parce que aprèla taille il ne reste que return
      0
  2. Dalfab Messages postés 638 Date d'inscription   Statut Membre Dernière intervention   102
     
    Bonjour,

    Dans la fonction coefficient(), la séquence
    if(controlleur) 
       coefficient(nbreCoef);
    ne demande pas de recommencer, mais s'auto-appelle en récursivité pour demander les coefficients puis à son retour, la boucle continue et les autres coefficients sont demandés. D'où un double affichage et un retour faux (le 1er coefficient erroné est toujours resté là!).

    On peut se servir du booléen controlleur pour reprendre la dernière saisie par :
    if ( controlleur ) {
       --j;             // reculer d'un indice pour le refaire
       coef.pop_back(); // supprimer la dernière entrée
      ////  ou bien
      //j = 0;          // revenir au debut
      //coef.clear();   // supprimer toutes les entrées
    }
    Attention, la fonction controlle() ne supprime rien du vector<> passé en paramètre, elle travaille sur une copie du vector<> qui sera vite oubliée dès la sortie de la fonction.
    0
    1. viktorfrankestein Messages postés 13 Statut Membre
       
      Merci pour la reponse

      je pense que les tableaux sont passés par reference en c++ donc quand je travaille sur un tableau dans une fonction ça le modifie partout ailleurs. n'est ce pas le cas?
      et aussi il n'ya pas de double affichage mais une double demande. les valeurs 5 et 4 c'est moi qui les ait entré de nouveau
      0
  3. Dalfab Messages postés 638 Date d'inscription   Statut Membre Dernière intervention   102
     
    Non les tableaux ne sont pas passés par référence en C++.
    Il y a une ambiguïté de vocabulaire sur ce qu'est un tableau :
    - deque<T> est un objet qui gère les tableaux dynamiques gérant la double entrée
    - vector<T> est un objet qui gère les tableaux dynamiques
    - array<T,N> est un objet qui gère les tableaux statiques
    - T [N] est un tableau 'brut'

    En C++ (comme en C) tout est toujours passé par copie sauf :
    - les tableaux 'bruts' qui sont passés en pointeurs (d'où l'impression d'un passage par référence)
    - les fonctions qui sont elles aussi passées en pointeurs.
    0
    1. viktorfrankestein Messages postés 13 Statut Membre
       
      qu'est ce qui se passe si j'ajoute un & quand je passe un tableau dynamique à une fonction?
      0
      1. Dalfab Messages postés 638 Date d'inscription   Statut Membre Dernière intervention   102 > viktorfrankestein Messages postés 13 Statut Membre
         
        L'esperluette permet d'indiquer un passage par référence, dans ce cas au lieu d'un passage par copie, on a un passage par référence.
        void fct( Type t ); // passage par copie (à éviter pour les types non scalaires car souvent non optimal, mais pas toujours)
        void fct( Type& t ); // passage par référence (lvalue seulement), pour une donnée que l'on veut modifier
        void fct( Type const& t ); // passage par const référence, pratique pour transmettre en lecture un type complexe (rvalue ou lvalue)
        void fct( Type&& t ); // passage 'optimal' d'une rvalue qui pourra être amputée si nécessaire
        0
    2. viktorfrankestein Messages postés 13 Statut Membre
       
      okay merci
      0