Utilisation de tableaux - programme débutant (besoin d'aide !)

Utilisation de tableaux - programme débutant (besoin d'aide !) - C++ - Programmation

Marsh Posté le 06-11-2016 à 19:28:07    

Salut !
 
c'est mon premier post sur le forum. Je suis étudiant en DUT Informatique en 1ère année. J'aurai besoin d'un petit peu d'aide ! Au niveau des tableaux en C++, il y a quelque chose dans le programme que je dois faire que je ne comprends pas.
 
En gros, mon programme doit être le suivant : l'utilisateur rentre une date (il rentre le jour dans une première variable, puis le mois, puis l'année), et le programme doit dire de quel jour de la semaine il s'agit. Par exemple, le 31/12/2003 est le jour 3. 0 correspond à Lundi, 2 à mardi, etc... jusqu'à 6 qui correspond au dimanche.
Pour ce faire, j'ai l'aide suivante : on doit saisir une date postérieure au 1/1/2000. Et le 1/1/2000 est le jour 5, donc un samedi.
 
J'ai fait mon programme en utilisant 3 procédures. Voici le code :
 
Programme principal

Code :
  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int jour, mois, annee, num = 0;
  6. void SaisieDate(int& jour, int& mois, int& annee);
  7. void ControleFev(int jour, int mois, int annee, bool& fin);
  8. void JourSem(int jour, int mois, int annee, int& num);
  9. bool continu = true; // declaration d'un booleen utilisé dans la procedure de controle du mois de fevrier
  10.      // ce booleen devient faux lorsqu'une date rentree au niveau du mois de fevrier est invalide
  11.      // exemple : le 30 fevrier 2016 n'existe pas
  12. // procedure de controle des saisies de la date
  13. SaisieDate(jour, mois, annee);
  14. // procedure de controle du mois de fevrier dans le cas d'annees bissextiles
  15. ControleFev(jour, mois, annee, continu);
  16. if (continu) // booleen de contrôle du mois de février : si il est vrai, l'annee n'est pas bissextile
  17. {
  18.  // procedure pour trouver le jour
  19.  JourSem(jour, mois, annee, num);
  20.  cout << "Le " << jour << "/" << mois << "/" << annee << " est le jour " << num << "." << endl;
  21. }
  22. system("PAUSE" );
  23. return 0;
  24. }


 
Procédure de saisie de la date

Code :
  1. #include <iostream>
  2. using namespace std;
  3. ///////////////////////////////////////////////////////////////////////////////////////////////////
  4. //  
  5. // PROCEDURE DE SAISIE ET DE CONTROLE DE LA DATE  
  6. // Entree : rien
  7. // Sortie : le jour, le mois, l'annee saisie stockés dans 3 variables jour, mois, annee
  8. // Note: des boucles de controles sont utilisées afin de vérifier que la date est valide
  9. //   le cas de février est traité dans une autre procédure
  10. //  
  11. ///////////////////////////////////////////////////////////////////////////////////////////////////
  12. void SaisieDate(int& jour, int& mois, int& annee)
  13. {
  14.  cout << "Entrez une date posterieure au 1/1/2000." << endl;
  15.  // Contrôle des saisies
  16.  do
  17.  {
  18.   cout << "Saisir le jour : ";
  19.   cin >> jour;
  20.   cout << endl;
  21.  } while (jour <= 0 || jour >= 32);
  22.  do
  23.  {
  24.   cout << "Saisir le mois : ";
  25.   cin >> mois;
  26.   cout << endl;
  27.  } while (mois <= 0 || mois >= 13);
  28.  do
  29.  {
  30.   cout << "Saisir l'annee : ";
  31.   cin >> annee;
  32.   cout << endl;
  33.  } while (annee < 2000);
  34. }


 
Procédure de contrôle au niveau du mois de février

Code :
  1. #include <iostream>
  2. using namespace std;
  3. ///////////////////////////////////////////////////////////////////
  4. //
  5. // PROCEDURE DE CONTROLE DU MOIS DE FEVRIER (ANNEE BISSEXTILE OU NON)
  6. // Entree : les dates saisies
  7. // Sortie : booleen devenant faux si la date rentrée de février est invalide
  8. //
  9. //////////////////////////////////////////////////////////////////
  10. void ControleFev(int jour, int mois, int annee, bool& continu)
  11. {
  12. // ANNEE BISSEXTILE
  13. if (((annee % 4 == 0) && (annee % 100 != 0)) || (annee % 400 == 0))
  14. {
  15.  cout << "L'annee " << annee << " est bissextile ! " << endl;
  16.  if (mois == 2) // FEVRIER
  17.  {
  18.   if (jour > 29)
  19.   {
  20.    cout << "Le " << jour << "/" << mois << "/" << annee << " est invalide." << endl;
  21.    continu = false;
  22.   }
  23.  }
  24. }
  25. else // ANNEE NON BISSEXTILE
  26. {
  27.  if (mois == 2) // FEVRIER
  28.  {
  29.   if (jour > 28)
  30.   {
  31.    cout << "Le " << jour << "/" << mois << "/" << annee << " est invalide." << endl;
  32.    continu = false;
  33.   }
  34.  }
  35. }
  36. }


 
Procédure de calcul du jour de la semaine
 

Code :
  1. #include <iostream>
  2. using namespace std;
  3. void JourSem(int jour, int mois, int annee, int& num)
  4. {
  5. int Jour[200000];
  6. int Mois[12]{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  7. int Num[7]{ 0, 1, 2, 3, 4, 5, 6 };
  8. int i, p, c, b, d, e, f;
  9. int div;
  10. if (((annee % 4 == 0) && (annee % 100 != 0)) || (annee % 400 == 0))
  11. {
  12.  Mois[1] = 29;
  13. }
  14. else
  15. {
  16.  Mois[1] = 28;
  17. }
  18. p = 0;
  19. Jour[p] = 0;
  20. i = annee - 2000;
  21. while (Jour[p] < (365 * i))
  22. {
  23.  Jour[p+1] = p + 1;
  24.  p = p + 1;
  25. }
  26. div = ((annee - 2000) / 4);
  27. c = 1;
  28. while (c < div)
  29. {
  30.  Jour[p + 1] = p + 1;
  31.  p = p + 1;
  32. }
  33. b = mois - 1;
  34. d = 0;
  35. while (d < b)
  36. {
  37.  e = 0;
  38.  for (Mois[d] = 1; Mois[d] < Mois[e]; Mois[d]++)
  39.  {
  40.   Jour[p + 1] = p + 1;
  41.   p = p + 1;
  42.  }
  43.  e = e + 1;
  44.  d = d + 1;
  45. }
  46. f = 1;
  47. while (f < jour)
  48. {
  49.  Jour[p + 1] = p + 1;
  50.  p = p + 1;
  51. }
  52. if (((Jour[p] % 7) == 0) || (Jour[p] == 1))
  53. {
  54.  num = 5;
  55. }
  56. else
  57. {
  58.  if (((Jour[p] % 7) == 1) || (Jour[p] == 2))
  59.  {
  60.   num = 6;
  61.  }
  62.  else
  63.  {
  64.   if (((Jour[p]) % 7 == 2) || (Jour[p] == 3))
  65.   {
  66.    num = 0;
  67.   }
  68.   else
  69.   {
  70.    if (((Jour[p]) % 7 == 3) || (Jour[p] == 4))
  71.    {
  72.     num = 1;
  73.    }
  74.    else
  75.    {
  76.     if (((Jour[p]) % 7 == 4) || (Jour[p] == 5))
  77.     {
  78.      num = 2;
  79.     }
  80.     else
  81.     {
  82.      if (((Jour[p]) % 7 == 5) || (Jour[p] == 6))
  83.      {
  84.       num = 3;
  85.      }
  86.      else
  87.      {
  88.       if (((Jour[p]) % 7 == 6) || (Jour[p] == 7))
  89.       {
  90.        num = 4;
  91.       }
  92.      }
  93.     }
  94.    }
  95.   }
  96.  }
  97. }
  98. }


 
 
Mon problème se situe plutôt au niveau de la dernière procédure, celle du calcul du jour de la semaine. J'ai décidé de déclarer un tableau assez grand, et d'attribuer un numéro à chaque jour, jusqu'au jour saisi. Ensuite, je regarde la divisibilité de ce nombre par 7, et j'en déduis le numéro du jour.
 
Le truc c'est que ça marche pour le 1/1/2000, mais dès que j'essaie le 2/1/2000 j'ai un debug error... Et pas la peine de parler d'un jour en 2001, le programme cesse tout bonnement de fonctionner...
J'ai l'impression que l'erreur se situe au niveau du tableau Jour[P]. Est-ce véritablement comme ça qu'on doit utiliser un tableau ? Ma méthode est-elle adéquate ? Qu'ai-je fait de mal ?
 
Si quelqu'un pourrait éclairer ma lanterne, ce serait vraiment sympa...
 
En tout cas, merci par avance !
 
EDIT : désolé, j'ai mis des balises spoiler pour que ce soit un peu moins chiant, mais ça n'a pas l'air de fonctionner... :/

Message cité 2 fois
Message édité par vekoros le 07-11-2016 à 09:51:53
Reply

Marsh Posté le 06-11-2016 à 19:28:07   

Reply

Marsh Posté le 07-11-2016 à 11:25:38    

vekoros a écrit :

f = 1;
 
 while (f < jour)
 {
  Jour[p + 1] = p + 1;
  p = p + 1;
 }
 


Tu sors quand de cette boucle ?

Reply

Marsh Posté le 07-11-2016 à 11:31:36    

Addendum:  
tu auras le même problème avec  

vekoros a écrit :

div = ((annee - 2000) / 4);
 c = 1;
 
 while (c < div)
 {
  Jour[p + 1] = p + 1;
  p = p + 1;
 }


Reply

Marsh Posté le 08-11-2016 à 12:42:53    

Très juste ! je n'avais pas fait attention. J'aurais dû incrémenter les compteurs. Merci !

Reply

Marsh Posté le 28-11-2016 à 19:54:14    

Hi all, je me permets de poster ici
 
Pour m'entrainer j'ai fait l'exercice : trouver quel jour de la semaine à partir d'une date.  
 
Ça fonctionne.
 
Vos observations sont les bienvenues !
 
C'est bon de faire comme j'ai fait ?  Je me sert de fonctions mais j'ai pas de return, sinon il me faut wat mille variables et je me perds, et puis (sur un autre programme) j'avais eu aussi des problèmes "xxx was not declared in this scope"
 

Code :
  1. #include <iostream>
  2. #include <string>
  3. #include <array>
  4. // programme qui fait correspondre un jour de la semaine à une date. Basé sur le 01/01/1600
  5. // ========================================================================================
  6. int day, month, year;
  7. void dateEntry()  {
  8.     std::cout << "\n Entrez le jour (ex : 17) : ";
  9.     std::cin >> day;
  10.     std::cout << " Entrez le mois (ex : 04) : ";
  11.     std::cin >> month;
  12.     std::cout << " Entrez l'annee (ex : 1925) : ";
  13.     std::cin >> year;
  14. }
  15. int daysInFullYears{0}, daysInFullMonths{0};  // nb de jours pour les années / pour les mois
  16. void dIFY()  {  // calcul de daysInFullYears : le nombre de jours total dans les années pleines
  17.     int anneeEnCours=1600;
  18.     bool bissextile{0};
  19.     for (anneeEnCours; anneeEnCours<year; anneeEnCours++)
  20.     {
  21.         bissextile =0;
  22.         if (((anneeEnCours%4==0)&&(anneeEnCours%100!=0))||(anneeEnCours%400==0)&&(anneeEnCours%100==0))
  23.         {
  24.             bissextile =1;
  25.         }
  26.         daysInFullYears +=(365+bissextile);
  27.     }
  28. }
  29. void dIFM()  {  // calcul de daysInFullMonths : le nombre de jours total dans les mois pleins
  30.     std::array<int, 12>monthTable;
  31.     monthTable[0]=31; // janvier
  32.     monthTable[1]=28;
  33.     monthTable[2]=31;
  34.     monthTable[3]=30; // avril
  35.     monthTable[4]=31;
  36.     monthTable[5]=30;
  37.     monthTable[6]=31;
  38.     monthTable[7]=31; // aout
  39.     monthTable[8]=30;
  40.     monthTable[9]=31;
  41.     monthTable[10]=30;
  42.     monthTable[11]=31; // decembre
  43.     int fullMonths=(month-1);
  44.     if (((year%4==0)&&(year%100!=0))||(year%400==0)&&(year%100==0))
  45.     {
  46.         monthTable[1]=29;
  47.     }
  48.     for (int i{0}; i<fullMonths; i++)
  49.     {
  50.         daysInFullMonths+=monthTable[i];
  51.     }
  52. }
  53. void amountAndFinalDay()  {  // calcul final = nb de jours total et attribution du jour de la semaine
  54.     std::array<std::string, 7> daysOfWeek;
  55.     daysOfWeek[0]="Vendredi";
  56.     daysOfWeek[1]="Samedi";
  57.     daysOfWeek[2]="Dimanche";
  58.     daysOfWeek[3]="Lundi";
  59.     daysOfWeek[4]="Mardi";
  60.     daysOfWeek[5]="Mercredi";
  61.     daysOfWeek[6]="Jeudi";
  62.     int daysFinalAmount=(daysInFullYears+daysInFullMonths+day);  // total du nb jours
  63.     std::string finalDay = daysOfWeek[daysFinalAmount%7];
  64.     std::cout << "\n Le " << day << "-" << month << "-" << year << " correspond a un "<< finalDay << std::endl << std::endl;
  65. }
  66. int main() {
  67.     std::cout << "\n ===================================================" << std::endl;
  68.     std::cout << " Calcul du jour de la semaine en fonction d'une date" << std::endl;
  69.     std::cout << "\t\t Lundi a Dimanche" << std::endl;
  70.     std::cout << "\tFonctionne a partir du 1 - 1 - 1600" << std::endl;
  71.     std::cout << "\t    Par Harvey - Novembre 2016" << std::endl;
  72.     std::cout << " ===================================================" << std::endl;
  73.     bool playAgain=true;
  74.     std::string pAgain="";
  75.     while (playAgain)
  76.     {
  77.         dateEntry();
  78.         dIFY();  // calcul du nb de jours dans les années entières (daysInFullYears)
  79.         dIFM();  // calcul du nb de jours dans les mois entiers (daysInFullMonths)
  80.         amountAndFinalDay();  // Calcul du nb total de jours et calcul du jour final de la semaine
  81.         std::cout << "\n Nouveau calcul ? Taper O/N ";
  82.         std::cin >> pAgain;
  83.         if ((pAgain=="N" ) || (pAgain=="n" ))
  84.         {
  85.             playAgain=false;
  86.         }
  87.         daysInFullYears=0; daysInFullMonths=0;  // réinitialisations sinon ça cumule
  88.     }
  89. }

Reply

Marsh Posté le 28-11-2016 à 20:32:25    

[:max evans] variables globales pour passer des paramètres à des fonctions => à fuire comme la peste. Ça fonctionne sur des cas simples comme ici, mais ça devient très très vite le bordel total.
 
En règle générale, les variables globales devraient être initialisées une fois au démarrage et on n'y touche plus après. Si on est obligé de modifier une variable globale, il est préférable d'encapsuler ça dans une API et éviter les accès direct.

Reply

Marsh Posté le 28-11-2016 à 21:09:42    

ok je m'en doutais, tu le confirmes.
 
Bon ben j'ai du boulot !
 
merci

Reply

Marsh Posté le 29-11-2016 à 09:47:38    

Comme tu indiques [C++], pourquoi ne pas envisager tout çà avec une (ou des) classe(s) ?

Reply

Marsh Posté le 29-11-2016 à 13:21:42    

Je me dis qu'il faut dans un premier temps que je m'entraine avec les fonctions, qui me semblent d'ailleurs plus simples que les classes.  J'ai bon ?

Reply

Marsh Posté le 29-11-2016 à 16:28:31    

Pas forcément.
 
Tes variables et tes fonctions peuvent constituer les membres d'une classe.
 
Cela te permet, entre autres, de restreindre la portée des variables et/ou de t'affranchir de les passer en paramètres.
 
Suppose que tu encapsules ton problème dans une classe. Ex:

Code :
  1. class MaDate
  2. {
  3.     int day, month, year;
  4.     std::string finalDay;
  5.     int dIFY(); // nombre de jours total dans les années pleines
  6.     int dIFM(); // nombre de jours total dans les mois pleins  
  7.     void dFD(); // calcul de finalDay
  8. public:
  9.     MaDate();
  10.     bool Entry(); // saisie  
  11.     void Display();
  12. };


 
ton main() pourrait ressembler à

Code :
  1. int main()
  2. {
  3.     MaDate D;
  4.     bool playAgain = true;
  5.     // bla bla
  6.     while( playAgain )
  7.     {
  8.         if( D.Entry() )
  9.             D.Display();
  10.         std::cout << "\n Nouveau calcul ? Taper O/N ";
  11.         std::cin >> pAgain;
  12.         // bla bla
  13.     }
  14. }


 
 

Reply

Marsh Posté le 29-11-2016 à 16:28:31   

Reply

Marsh Posté le 29-11-2016 à 18:02:50    

Génial
 
Je vais essayer  
 
Dans ton code :
 
    Je déduis que ce qui est avant public est privé.
 
    A quoi sert le MaDate() juste en dessous de public  ?
 
    Mes fonctions dIFY etc, je les écris directement dans la classe ? Tu n'as pas mis les {} alors je me demande si elles sont déclarées dans la classe et écrites en dehors (avant la classe ?)
 
Merci !
 
Edit : bon, je me doc à donf sur les classes sur le cours openclassrooms


Message édité par Lt Ripley le 29-11-2016 à 19:33:39
Reply

Marsh Posté le 06-12-2016 à 09:13:37    

Pour répondre (tardivement) à tes questions, même si depuis le temps tu as dû trouver les réponses :
 
- par défaut, ce qui est déclaré dans une classe est privé. Tu ne mets à disposition que ce qui est nécessaire (en le passant en public)
 
- le MaDate() est ce qu'on appelle un constructeur. Quand tu vas faire ton nouvel objet (ici la ligne 3 du main), c'est cette fonction qui sera appelée. En général, tu peux t'en servir pour initialiser tes données.
 
- Les méthodes sont à définir dans un fichier .cpp : le code qu'a donné benriach doit être dans un fichier MaDate.h, et dans ton fichier MaDate.cpp, tu dois avoir le code des méthodes.
 
Hésites pas à poster ce que tu fais / tes questions :)
 
 :hello:

Reply

Marsh Posté le 06-12-2016 à 09:46:28    

Hello Osx-Wind
 
Merci pour tes infos
 
J'ai en effet bien avancé, j'ai créé un topic : http://forum.hardware.fr/forum2.ph [...] w=0&nojs=0
 
Tu peux aller aux derniers posts directement
 
N'hésite pas à faire part de tes observations, elles seront bienvenues !   :)


Message édité par Lt Ripley le 06-12-2016 à 10:45:36
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed