#pragma once
#ifndef saisieMR_deja
#define saisieMR_deja
#include <iostream>
#include <limits>
#include <string>
#include <fstream>

using namespace std;

/*  (\_/) fichier
___( . . )_/________________
classe de lecture de fichier
elle a un fonctionnement tres
pres de celui du pseudocode
standar utilisé.
elle permet d'utiliser les
operateur stream tout en ayant
une détection d'érreure
__________________________*/

class lecture
{
    ifstream fichier;           //l'objet du fichier
public:
    lecture (string nomFichier);    //constructeur avec ouverture de fichier
    bool ouvrire(string nomFichier);    //ouverture de fichier
    void fermer();      //fermeture du fichier
    operator bool ();   //surcharge d'operateur bool, usage bool test = lecture; retourne ok
    //lecture d'un Entier dans un fichier
    lecture & operator >> (int & entier);       //surcharge de l'operateur stream avec entier
    //lecture d'un nombre decimal dans un fichier
    lecture & operator >> (float & naturel);        //surcharge de l'operateur stream avec decimal
    //lecture d'une lettre dans un fichier
    lecture & operator >> (char & lettre);      //surcharge de l'operateur stream avec une lettre
    //lecture d'une string dans un fichier
    lecture & operator >> (string & mot);       //surcharge de l'operateur stream avec une string
    //lecture d'un tableau de charactere dans un fichier
    lecture & operator >> (char mot[]);       //surcharge de l'operateur stream avec une string
};

//constructeur avec ouverture de fichier
lecture::lecture (string nomFichier)
{
    ouvrire(nomFichier);
}

//ouverture de fichier
bool lecture::ouvrire(string nomFichier)
{
    fichier.open(nomFichier.c_str());       //ouverture du fichier
    if (fichier.fail())     //si le fichier est absent
    {
        cout << "le fichier \"" << nomFichier << "\" est absent\n";
        return false;
    }
    if (fichier.peek() == ifstream::traits_type::eof()) //si le fichier est vide
    {
        cout << "le fichier \"" << nomFichier << "\" est vide\n";
        return false;
    }
    return true;
}

//fermeture du fichier
void lecture::fermer()
{
    fichier.close();
}

lecture::operator bool ()    //surcharge d'operateur bool, usage bool test = lecture; retourne ok
{
    while (fichier.peek() == 32 || fichier.peek() == 10)    //verification de fin de fichier
        fichier.get();                                      //en sautant les ESPACEs et les NEWLINEs
    return fichier.good() || !fichier.eof();
}

//lecture d'un Entier dans un fichier
lecture & lecture::operator >> (int & entier)        //surcharge de l'operateur stream avec entier
{
    fichier >> entier;
    if (fichier.fail())                     //dans le cas d'un echec
    {
        entier = 0;
        cout << "erreur " << fichier.cur << " attendu entier" << endl;
    }
    return *this;                       //il doit se retourner lui-meme pour la prochaine variable
}

//lecture d'un nombre decimal dans un fichier
lecture & lecture::operator >> (float & naturel)     //surcharge de l'operateur stream avec decimal
{
    fichier >> naturel;
    if (fichier.fail())                     //dans le cas d'un echec
    {
        naturel = 0;
        cout << "erreur " << fichier.cur << " attendu naturel" << endl;
    }
    return *this;
}

//lecture d'une lettre dans un fichier
lecture & lecture::operator >> (char & lettre)       //surcharge de l'operateur stream avec une lettre
{
    lettre = fichier.get();
    if (fichier.fail())                     //dans le cas d'un echec
    {
        lettre = 0;
        cout << "erreur " << fichier.cur << " attendu charactere" << endl;
    }
    return *this;
}

//lecture d'une string dans un fichier
lecture & lecture::operator >> (string & mot)        //surcharge de l'operateur stream avec une string
{
    fichier >> mot;
    if (fichier.fail())                     //dans le cas d'un echec
    {
        mot = "";
        cout << "erreur " << fichier.cur << " attendu serie de charactere" << endl;
    }
    return *this;
}

//lecture d'une string dans un fichier
lecture & lecture::operator >> (char mot[])        //surcharge de l'operateur stream avec une string
{
    fichier >> mot;
    if (fichier.fail())                     //dans le cas d'un echec
    {
        cout << "erreur " << fichier.cur << " attendu serie de charactere" << endl;
    }
    return *this;
}

#endif
