#include <iostream>
#include <vector>
using namespace std;

constexpr int DIVZERO(33);

// ======================================================================
typedef std::vector<double> Mesures;

void acquerir_temp(Mesures& temp, unsigned int essai = 1, bool fail = false)
{
  /* Vous pourriez aussi ici coder une saisie par l'utilisateur... 
   */

  switch (essai) {
  case 1:
    temp = { 12.5, -0.5, 1.4, 0.0, 5.0 };
    break;
  case 2:
    temp = { 12.5, -0.5, 1.4, 5.0, 0.0 };
    break;
  default:
    if (fail)
      temp = { 12.5, 0.0, 1.4, 1.0, 5.0 };
    else
      temp = { 12.5, -0.5, 1.4, 1.0, 5.0 };
    break;
  }
}

void plot(double x) {
  cout << "PLOT: " << x << endl;
}

// ======================================================================
void plot_temp_inverse(Mesures const&);
double inverse(double);

// ======================================================================
int main()
{
  Mesures temperatures;
  constexpr unsigned int MAX_ESSAIS(2);
  unsigned int nb_essais(0);
  bool restart(false);

  do {
    ++nb_essais; restart=false;
    acquerir_temp(temperatures, nb_essais);
    try {
      plot_temp_inverse(temperatures);
    }
    catch (int i) {
      if (i == DIVZERO) {
	if (nb_essais < MAX_ESSAIS) {
	  cout << "Il faut resaisir les valeurs" << endl;
	  restart = true;
	} else {
	  cout << "Il y a déjà eu au moins " << MAX_ESSAIS << " essais."
               << endl;
	  cout << " -> abandon" << endl;
	}
      } else {
	cout << "Ne sais pas quoi faire -> abandon" << endl;
      }
    }
  } while (restart);

  return 0;
}

// ======================================================================
void plot_temp_inverse(Mesures const& t) 
{
  for (unsigned int i(0); i < t.size(); ++i) {
    // Exemple de traitement local partiel du problème
    // (ce n'est pas obligatoire).
    try {
      plot(inverse(t[i]));
    }
    catch (int j) {
      cerr << "Erreur : ";
      if (j == DIVZERO) {
	cerr << "la valeur " << i << " est nulle.";
      } else {
	cerr << "problème avec la valeur " << i;
      }
      cerr << endl;
      throw;
    }
  }
}

// =====================================================
double inverse(double x) 
{
  if (abs(x) < 1e-5) throw DIVZERO;
  return 1.0/x;
}
