#include <iostream>
#include <cstdio>
#include <fstream> //ifstream, ofstream
#include <cstdlib> //exit



 /*
  Exemple 1 : illustration des opérations sur les fichiers en lecture
  et les structures
 */


 using namespace std;

/* Définition de la structure etudiant et de constantes*/

const int longueurNom = 64 ;
const int nombreDeNotes = 10 ;
const int maxEtudiants = 128 ;

struct etudiant {
  char nom[longueurNom] ;
  float note[nombreDeNotes] ;
} ;



/* Manipulation du fichier */
bool ouvertureFichierLecture(ifstream& fichier,char nom[1024]) {
  fichier.open(nom) ;
  return fichier.good() ;
}

bool lireEtudiant(ifstream& fichier, struct etudiant &e) {
  int i ;
  fichier >> e.nom ;
  if (fichier.eof()) {
    return false ;
  }
  for (i = 0 ; i < nombreDeNotes; i++ ) {
    fichier >> e.note[i] ;
  }
  return true ;
}

void fermetureFichierLecture( ifstream& fichier) {
  fichier.close() ;
}

/* Manipulation de etudiant */

int lireTousLesEtudiants(ifstream& fichier,struct etudiant t[maxEtudiants]) {
  int nombreEtudiants ;

  nombreEtudiants = 0;
  while ( (nombreEtudiants < maxEtudiants)
	  && lireEtudiant(fichier, t[nombreEtudiants] ) ) {
    nombreEtudiants = nombreEtudiants + 1 ;
  }
  if ( ! fichier.eof()) {
    cerr << "Trop d'etudiants !!! " << endl ;
  }
  return nombreEtudiants ;
}

void afficheLigne(char c, float f) {
  int i ;
  for(i=0; i < (int) f;i++) {
    cout << c ;
  }
}

void afficheProfileEtudiant(struct etudiant e) {
  int i ;
  afficheLigne('_',80) ;
  cout << endl << e.nom << endl ;
  for (i = 0; i < nombreDeNotes; i++) {
    afficheLigne('+', e.note[i]) ;
    cout <<endl ;
  }
}

/* manipulation de la classe */

float moyenneClasse(struct etudiant te[maxEtudiants], int nombreEtudiants,
		    int matiere) {
  int i ;
  float total ;
  total = 0 ;
  for(i = 0; i < nombreEtudiants; i++) {
    total = total + te[i].note[matiere] ;
  }
  return (total / nombreEtudiants ) ;
}

void afficheProfileClasse(struct etudiant te[maxEtudiants],
			  int nombreEtudiants) {
  int i ;
  for(i = 0; i < nombreEtudiants; i++) {
    afficheProfileEtudiant(te[i]) ;
  }
  afficheLigne('_',80) ;
  cout << endl << "Profile moyen de la classe " << endl ;
  for (i = 0; i < nombreDeNotes; i++) {
    afficheLigne('+', moyenneClasse(te, nombreEtudiants, i)) ;
    cout <<endl ;
  }
} 

/* traitement principale */
int main(void) {
  int nombreEtudiants ;
  struct etudiant te[maxEtudiants] ;
  ifstream fichierNotes ;
  char nomFichier[1024] ;


  cout << endl << "Edition profile d'une classe" << endl ;
  cout << "entrez le nom du fichier :" << endl ;
  cin >> nomFichier ;
  if (!ouvertureFichierLecture(fichierNotes,nomFichier)) {
    cerr << "ouverture impossible "<< nomFichier << endl ;
    return -1 ;
  }
  nombreEtudiants = lireTousLesEtudiants( fichierNotes, te ) ;
  afficheProfileClasse( te, nombreEtudiants ) ;
  fermetureFichierLecture(fichierNotes) ;
  system("PAUSE");
  return 0 ;
}
