M2103 – TP5-Corrigés

Fichier Alarme.h


/**
 *
 * \file    Alarme.h
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  déclaration de la classe Alarme
 *
 **/
#ifndef _ALARME
#define _ALARME

namespace nsDigicode {

	class Alarme {
	  public:
		void declencher (void);
		
	}; // Alarme
	
} /* nsDigicode */

#endif /* _ALARME */

Fichier Alarme.cpp


/**
 *
 * \file    Alarme.cpp
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  définition de la classe Alarme
 *
 **/
#include <iostream>
#include <unistd.h>   // sleep()
using namespace std;
#include "Alarme.h"

void nsDigicode::Alarme::declencher (void) {
	while (true) {
		cout << "Alarme : la porte n'est pas fermée" << endl;
		sleep(1);
	} 
} // declencher()

Fichier Archivage.h


/**
 *
 * \file    Archivage.h
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  déclaration de la classe Archivage
 *
 **/
#ifndef _ARCHIVAGE
#define _ARCHIVAGE

namespace nsDigicode {

	class Archivage {
	  public:
		void archiver (int);
		
	}; // Archivage
	
} /* ns_Digicode */

#endif /* _ARCHIVAGE */

Fichier Archivage.cpp


/**
 *
 * \file    Archivage.cpp
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  définition de la classe Archivage
 *
 **/
#include <fstream>
#include <ctime>     // time_t, time ()

using namespace std; #include "Archivage.h" #define NOM_FIC "../DigicodeIUT/Archive.txt" #define MODE std::fstream::out | std::fstream::app void nsDigicode::Archivage::archiver (int code) { ofstream leFichier (NOM_FIC,MODE); time_t dateActuelle; time (&dateActuelle); leFichier << "Code : " << code << " Date : " << ctime (&dateActuelle) << endl; leFichier.close (); } //archiver()

Fichier BD.h


/**
 *
 * \file    BD.h
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  déclaration de la classe BD
 *
 **/
#ifndef _BD
#define _BD

namespace nsDigicode {

	class BD {
	  public:
		bool verifier (int);
		
	}; // BD
	
} /* ns_Digicode */

#endif /* _BD */

Fichier BD.cpp


/**
 *
 * \file    BD.cpp
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  définition de la classe BD
 *
 **/
#include <iostream>           
#include <fstream>           
using namespace std;
#include "BD.h"

#define NOM_FIC "../DigicodeIUT/Base.txt"

bool nsDigicode::BD::verifier (int code) {
int lu = -1; cout << "Vérification du code" << endl; ifstream leFichier; leFichier.open (NOM_FIC); while (!leFichier.eof () && lu != code ) leFichier >> lu; leFichier.close (); if (lu != code) cout << "Code erroné" << endl; return lu == code; } //verifier()

Fichier Capteur.h


/**
 *
 * \file    Capteur.h
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  déclaration de la classe Capteur
 *
 **/
#ifndef _CAPTEUR
#define _CAPTEUR

namespace nsDigicode {

	class Capteur {
	  public:
		int detecter (void);
		
	}; // Capteur
	
} /* ns_Digicode */

#endif /* _CAPTEUR */

Fichier Capteur.cpp


/**
 *
 * \file    Capteur.cpp
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  définition de la classe Capteur
 *
 **/
#include "Capteur.h"                  
#include "kbhit.h"


int nsDigicode::Capteur::detecter (void) { return  _kbhit(); }   

Fichier Chrono.h


/**
 *
 * \file    Chrono.h
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  déclaration de la classe Chrono
 *
 **/
#ifndef _CHRONO
#define _CHRONO

namespace nsDigicode {

	class ObjetTempo;
	
	class Chrono 	{
		bool actif;
		static void* compter (void *);
	  public:
		void demarrer (ObjetTempo*);
		void arreter (void);
		Chrono (void);
		
	}; // Chrono
	
} /* ns_Digicode */

#endif /* _CHRONO */

Fichier Chrono.cpp


/**
 *
 * \file    Chrono.cpp
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  définition de la classe Chrono
 *
 **/
#include 
#include 

using namespace std;

#include 
#include "ObjetTempo.h"
#include "Chrono.h"         

void nsDigicode::Chrono::arreter (void) { actif = false; } 

nsDigicode::Chrono::Chrono (void) { actif = false; }

void* nsDigicode::Chrono::compter (void * p) { 
	double duree   = (clock_t) ( (ObjetTempo *) p)->getDelai ();
	Chrono *lec    = ( (ObjetTempo *) p)->getChrono ();
	clock_t debut  = clock ();
	double tempsEcoule = (clock () - debut) / CLOCKS_PER_SEC;
	lec->actif = true;
	while (lec->actif && tempsEcoule<duree) {="" tempsecoule="(clock" ()="" -="" debut)="" clocks_per_sec;="" }="" if="" (tempsecoule="">= duree ) {
		 ( (ObjetTempo *) p)->finTempo ();
		lec->actif = false;
	}
	pthread_exit (NULL);
	
} //compter()

void nsDigicode::Chrono::demarrer (ObjetTempo * a) {  
	pthread_t thread;
	while (actif) std::cout.flush ();
//	double duree = a->getDelai ();
	std::cout.flush ();
	pthread_create (&thread, NULL, compter, (void *) a);
	
} //demarrer()
</duree)>

Fichier Clavier.h


/**
 *
 * \file    Clavier.h
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  déclaration de la classe Clavier
 *
 **/
#ifndef _CLAVIER
#define _CLAVIER

namespace nsDigicode {

	class Clavier {
	  public:
		int saisieChiffre (void);
		
	}; // Clavier
	
} /* ns_Digicode */

#endif /* _CLAVIER */

Fichier Clavier.cpp


/**
 *
 * \file    Clavier.cpp
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  définition de la classe Clavier
 *
 **/
#include 

#include "Clavier.h"                  
#include "kbhit.h"
using namespace std;

int nsDigicode::Clavier::saisieChiffre (void) {
	int c ;
	if (c = _kbhit()) {
		cout << "*" << flush;
		return c - '0';
	}	
	return -1;
	
} // saisieChiffre()  

Fichier Interface.h


/**
 *
 * \file    Interface.h
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  déclaration de la classe Interface
 *
 **/
#ifndef _INTERFACE
#define _INTERFACE
#include 

#include "ObjetTempo.h"
#include "Clavier.h"
#include "Voyant.h"
#include "Chrono.h"

namespace nsDigicode {

	class Interface : public ObjetTempo {
		int     nbChiffresAttendus;
		Clavier leClavier;
		Voyant  leVoyantVert;
		Voyant  leVoyantRouge;
		
		void statut (std::string = "\n");
		
	public:
		int saisieCode (void);
		Interface (Chrono*, int, int);
		
	}; // Interface
	
} /* ns_Digicode */

#endif /* _INTERFACE */

Fichier Interface.cpp


/**
 *
 * \file    Interface.cpp
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  définition de la classe Interface
 *
 **/
#include 
#include 
using namespace std;

#include "Interface.h"                  
#include "Chrono.h"

nsDigicode::Interface::Interface (Chrono * lech, int d, int nbca) : 
	ObjetTempo (lech, d),
	leVoyantRouge (rouge, eteint),
	leVoyantVert (vert, eteint),
	nbChiffresAttendus (nbca)
{}  

void nsDigicode::Interface::statut (string s) {
	cout << endl     << "VERT"  << setw(4) << leVoyantVert.getStatut() 
		 << setw(7)  << "ROUGE" << setw(4) << leVoyantRouge.getStatut() 
		 << setw(24) << s << flush;
		 
} // statut()

int nsDigicode::Interface::saisieCode (void) { 
    int code, chiffreLu, nbChiffresLus;
    attente = false;
    do {
	leVoyantVert.eteindre ();
	leVoyantRouge.allumer ();
	statut ("Entrez votre code : "); 
	cin.clear ();
	code = 0;
	while ((code = leClavier.saisieChiffre ()) == -1);
	nbChiffresLus = 1;
	leVoyantVert.allumer ();
	statut ("Continuez la saisie : ");
	attente = true;
	leChrono->demarrer (this);
	while (attente && nbChiffresLus < nbchiffresattendus) {
while (attente && (chiffrelu = leClavier.saisieChiffre())
== -1);
if (attente) {
code = code * 10 + chiffrelu;
nbchiffreslus++;
if (nbchiffreslus == nbchiffresattendus)
lechrono->arreter ();
} else cout << endl << "Temps ecoulé - Fin de saisie" << endl; } while (nbChiffresLus < nbChiffresAttendus ); leVoyantRouge.eteindre (); statut (); return code; } // saisieCode() </nbchiffresattendus)>

Fichier kbhit.h


/**
 *
 * \file    kbhit.h
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  déclaration de la fonction _kbhit()
 *
 **/
int _kbhit (void);

Fichier kbhit.cpp


/**
 *
 * \file    kbhit.cpp
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  définition de la fonction _kbhit()
 *
 **/
#include 
#include 
#include 
#include 
#include 

using namespace std;
 
void set_mode (bool want_key) {
	static struct termios old, cur;
	if (!want_key) {
		tcsetattr (STDIN_FILENO, TCSANOW, &old);
		return;
	}
 
	tcgetattr (STDIN_FILENO, &old);
	cur = old;
	cur.c_lflag &= ~(ICANON | ECHO);
	tcsetattr (STDIN_FILENO, TCSANOW, &cur);
}
 
int _kbhit (void) {
	int c = 0;
	struct timeval tv;
	set_mode (true);
	fd_set fs;
	tv.tv_usec = tv.tv_sec = 0;
 
	FD_ZERO (&fs);
	FD_SET  (STDIN_FILENO, &fs);
	select  (STDIN_FILENO + 1, &fs, 0, 0, &tv);
 
	if (FD_ISSET (STDIN_FILENO, &fs)) {
		c = cin.get ();
		set_mode (false);
	}
	return c;
	
} // _kbhit()

Fichier ObjetTempo.h


/**
 *
 * \file    ObjetTempo.h
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  déclaration de la classe ObjetTempo
 *
 **/
#ifndef _OBJETTEMPO
#define _OBJETTEMPO

#include "Chrono.h"

namespace nsDigicode {

	class ObjetTempo {
		int delai;
	  protected:
		bool    attente;
		Chrono* leChrono;
	  public:
		Chrono* getChrono (void);
		void    finTempo  (void);
		ObjetTempo (Chrono*, int);
		int getDelai (void) const;
		
	}; // ObjetTempo
	
} /* ns_Digicode */

#endif /* _OBJETTEMPO */

Fichier ObjetTempo.cpp


/**
 *
 * \file    ObjetTempo.cpp
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  définition de la classe ObjetTempo
 *
 **/
#include "ObjetTempo.h"                  
#include "Chrono.h"
using namespace std;

nsDigicode::ObjetTempo::ObjetTempo (Chrono* lech, int d) :
	leChrono (lech),
	delai (d) {}  

void nsDigicode::ObjetTempo::finTempo (void) { attente = false; }  

int nsDigicode::ObjetTempo::getDelai (void) const { return delai; }   

nsDigicode::Chrono* nsDigicode::ObjetTempo::getChrono (void) { return leChrono; }   

Fichier Porte.h


/**
 *
 * \file    Porte.h
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  déclaration de la classe Porte
 *
 **/
#ifndef _PORTE
#define _PORTE

#include "ObjetTempo.h"
#include "Capteur.h"
#include "Chrono.h"

namespace nsDigicode {

	class Porte : public ObjetTempo {
		Capteur leCapteur;
		bool fermer();
	  public:
		bool ouvrir();
		Porte(Chrono*, int);
		
	}; // Porte
	
} /* ns_Digicode */

#endif /* _PORTE */

Fichier Porte.cpp


/**
 *
 * \file    Porte.cpp
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  définition de la classe Porte
 *
 **/
#include 

#include "Porte.h"                  
using namespace std;

nsDigicode::Porte::Porte (Chrono * lech, int d) : ObjetTempo(lech, d) {}  

bool nsDigicode::Porte::ouvrir (void) {
	attente = true;
	leChrono->demarrer(this);
	cout << "Vous pouvez entrer" << endl;
	while (attente && !leCapteur.detecter());
	if (attente)
		return fermer ();
	else {
		cout << "Temps écoulé - La porte se verrouille" << endl;
		return true;
	}
} // ouvrir()

bool nsDigicode::Porte::fermer (void)  
{
	cout << "Porte ouverte : fermez la porte" << endl;
	while (attente && !leCapteur.detecter ());
	if (attente)
	{
		leChrono->arreter ();
		attente = false;
		cout << "Vous avez fermé la porte" << endl;
		return true;
	}
	else
		return false;
}  // fermer()

Fichier Voyant.h


/**
 *
 * \file    Voyant.h
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  déclaration de la classe Voyant
 *
 **/
#ifndef _VOYANT
#define _VOYANT

#include 

namespace nsDigicode {

	enum Color {rouge,  vert};
	enum Etat  {allume, eteint};
	
	class Voyant {
		Color couleur;
		Etat et;
	  public:
		void allumer  (void);
		void eteindre (void);
		Voyant (Color c, Etat e);
		std::string getStatut (void) const;
		
	}; // Voyant
	
} /* ns_Digicode */

#endif /* _VOYANT */

Fichier Voyant.cpp


/**
 *
 * \file    Voyant.cpp
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  définition de la classe Voyant
 *
 **/

#include "Voyant.h"                  

nsDigicode::Voyant::Voyant(Color c, Etat e) {  
	couleur = c;
	et = e;
	
}  // Voyant()

void nsDigicode::Voyant::allumer (void) { 
	if (et == eteint)
		et = allume;
	
}  // allumer()

void nsDigicode::Voyant::eteindre (void) {
	if (et == allume)
		et = eteint;
	
} // eteindre()

string nsDigicode::Voyant::getStatut (void) const {
	if (et == allume) return "ON";
	return "OFF";
	
} // getStatut()

Fichier Systeme.h


/**
 *
 * \file    Systeme.h
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  déclaration de la classe Systeme
 *
 **/
#ifndef _SYSTEME
#define _SYSTEME

#include "Interface.h"
#include "Porte.h"
#include "Alarme.h"
#include "BD.h"
#include "Archivage.h"
#include "Chrono.h"

namespace nsDigicode {

	class Systeme {
		Interface lInterface;
		Porte     laPorte;
		Alarme    lAlarme;
		BD        laBD;
		Archivage lArchive;
		Chrono    leChrono;
	  public:
		Systeme (int, int, int);
		
	}; // Systeme
	
} /* ns_Digicode */

#endif /* _SYSTEME */

Fichier Systeme.cpp


/**
 *
 * \file    Systeme.cpp
 *
 * \authors S. Nabitz
 *
 * \date    04/04/2018
 *
 * \version V1.0
 *
 * \brief  définition de la classe Systeme
 *
 **/
#include                   
using namespace std;

#include "Systeme.h"                  

#define DELAI_CLAVIER 5
#define DELAI_PORTE 8
#define NB_CHIFFRES_CLAVIER 4

nsDigicode::Systeme::Systeme (int dc, int dp, int nbca) :
		lInterface (&leChrono, dc, nbca), laPorte (&leChrono, dp) { 	
	int c;
	while (true) {
	   lArchive.archiver (c = lInterface.saisieCode());
	   if (laBD.verifier (c)) {
		   if (!laPorte.ouvrir ()) 
			   lAlarme.declencher ();
	   }
	}
} // Systeme()

int main (void) {
	nsDigicode::Systeme s (DELAI_CLAVIER, DELAI_PORTE, NB_CHIFFRES_CLAVIER);
	
	return 0;
	
} // main()