IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Observer l'état d'une variable


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 206
    Points : 79
    Points
    79
    Par défaut Observer l'état d'une variable
    Salut à tous

    Ma question va sûrement vous paraître triviale, mais je ne trouve pas de réponse.

    Voici un bout de mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int status;
     
    status = fileReceptor.read(AUTO_DELAY, m_command_auto_delay);
    if(status != SUCCESS_OPERATION) return status;
    status = fileConfig.read(DURATION_CYCLE, m_duration_cycle);
    if(status != SUCCESS_OPERATION) return status;
    status = fileConfig.readDelays(m_date, m_date_passage_meridien, m_listDelays);
    if(status != SUCCESS_OPERATION) return status;
     
    return SUCCESS;
    Comme vous le voyez c'est très répétitif, et j'aimerais améliorer ce code.
    J'aimerais observer le status, et dès qu'il passe à une certaine valeur je stoppe.
    Au début j'avais codé une boucle while, mais je me suis dit qu'il regardait le status seulement à la fin de la boucle, donc si ça plante au milieu, ça ne se verra pas.

    Il doit sûrement y avoir un autre moyen, tout con en plus, mais je ne vois pas

    Merci de m'apporter votre aide

  2. #2
    Membre averti Avatar de vikki
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    292
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 292
    Points : 302
    Points
    302
    Par défaut
    Hello,
    Pourquoi pas enregistrer tes fonctions 'read' dans un vecteur de boost::function<int()>. Tu peux ensuite les appeler dans une simple boucle for:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    for(int i=0; i< functions.size(); i++)
    {
         if( !functions[i]() )
             break;
    }
    C'est peut être également faisable avec boost.signal s'il y a moyen de spécifier une condition d'arrêt.

    EDIT: si tu n'as que trois conditions à tester, ca ne vaut peut être pas le coup de chercher à optimiser...

  3. #3
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Pour éviter de tester partout les codes erreurs, on recourt généralement à une gestion par exception (par exemple, en wrappant la méthode read si tu ne peux pas la modifier, et en lançant une exception si le status_code est différent de SUCCESS_OPERATION).

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 206
    Points : 79
    Points
    79
    Par défaut
    Salut à vous deux, vos réponses sont intéressantes

    Je vais regarder le fonctionnement de boost::function. En fait j'ai plusieurs dizaines de conditions comme ça a tester, c'est pour ça que je cherche à économiser les lignes de code.

    @white_tentacle: tu entends quoi par "wrapper la méthode read" ? L'idée serait de faire un throw(exception) dans la méthode read, et un catch dans les méthodes qui utilisent read ?

  5. #5
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    C'est l'idée.

    C'est intéressant si tu as besoin de savoir qu'un traitement a réussi dans son intégralité, ou qu'il a échoué, mais pas forcément de savoir où il a échoué.

    Du coup, tu peux te permettre un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    try 
    {
      instruction1;
      instruction2;
      instruction3;
    }
    catch(readexception&)
    {
      // traitement qui ne dépend pas de l'instruction qui a échoué
    }
    Ici, vu que tout ce que tu fais, c'est retourner l'erreur renvoyée en cas d'erreur, ça me semble approprié.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 206
    Points : 79
    Points
    79
    Par défaut
    Je trouve le principe super, mais en pratique j'ai des difficultés à lancer des throw :s

    Par exemple j'ai une fonction read qui pour l'instant fonctionne comme ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    //cette fonction ne lit pas dans un fichier mais dans un vector de string.
    int File::read(int lineNumber, int & sortie) {
    	if(!m_lines.empty() && lineNumber < (int) m_lines.size()) {
    		try {
    			sortie = atoi(m_lines.at(lineNumber).c_str());
    			return SUCCESS_READING;
    		} catch(exception &e) {
    			cout << "You must clean the file before reading.";
    			cout << e.what();
    			return FAIL_READING_CONFIG;
    		}
    	} else {
    		cout << "The container is empty, or the index is out of range." << endl;
    		return FAIL_READING_CONFIG;
    	}
    }
    Ici l'idée c'était de faire un throw si la conversion avec atoi a échouée, mais je ne vois pas comment procéder, à part relancer l'exception

  7. #7
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Déjà, tu es mal barré : le atoi que je connais le lance pas d'exception en cas d'échec . Tu peux regarder du côté de boost::lexical_cast pour faire ce que tu veux (et là, tu auras une belle exception).

    Ensuite, il faut savoir que dans un bloc catch, écrire "throw;" tel que relance la dernière exception attrapée.

    Enfin, tout dépend de ton besoin... Mais ta fonction read peut très bien lancer deux exceptions : LineOutOfRangeException et InvalidDataException, qui héritent toutes les deux de FileReadException. En fonction des besoins, le client choisira de gérer indifféremment les deux, ou de faire la distinction.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 206
    Points : 79
    Points
    79
    Par défaut
    En fait je n'arrive pas à utiliser boost. La raison est stupide: j'ai un makefile très compliqué qui vient du framework qu'on me force à utiliser, et je n'arrive pas à inclure boost dedans.

    C'est pour ça que je passe par atoi, qui effectivement retourne un 0 en cas d'échec. C'est d'autant plus nul que dans plusieurs cas je vais lire des 0 ... Je ne peux donc pas savoir si atoi m'a bien retourné la valeur, ou un échec. C'est vraiment pas top pour lancer un throw donc :s

    Au final je ne vois pas comment gérer les exceptions autrement que ce que j'ai fais

  9. #9
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Citation Envoyé par scheme Voir le message
    Au final je ne vois pas comment gérer les exceptions autrement que ce que j'ai fais
    Est-ce que tu réalises bien qu'en fait, là, tu ne gères pas du tout le cas où atoi échoue ?

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 206
    Points : 79
    Points
    79
    Par défaut
    Non je viens juste de réaliser

    Aw je vais avoir du mal à m'en sortir

  11. #11
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    il y a plusieurs solutions pour t'en sortir :

    - si tu sais que la valeur que tu lis n'es jamais 0, alors tu peux faire quelque chose du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int ret = atoi(val);
    if(ret == 0) { throw fail_reading_exception(); }
    Si maintenant, ta valeur peut être zéro, il va falloir identifier les cas où atoi renvoie 0 parce qu'il a échoué, et ceux où il renvoie 0 parce qu'il a lu 0 (ah, les joies des api pourries...). Tu peux faire quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    function monAtoiQuiLeveUneException(char const * val)
    {
      int ret = atoi(val);
      if(ret == 0)
      {
        if(val[0] == 0) // cas d'une chaîne vide
          throw fail_reading_exception();
        else if(val[0] == '0' && val[1] == 0) // cas d'un 0 suivi d'un \0, c'est bien 0 qu'il faut lire
          return 0;
        else
          throw fail_reading_exception();
      }
    }

  12. #12
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par white_tentacle Voir le message
    il y a plusieurs solutions pour t'en sortir :
    Pour commencer, me pas utiliser atoi mais strtol si on veut faire de la detection d'erreur.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  13. #13
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    Pour commencer, me pas utiliser atoi mais strtol si on veut faire de la detection d'erreur.
    D'après ma page man, EINVAL n'est pas garanti... . Ca marche sur toutes les implémentations que tu connais ?

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 206
    Points : 79
    Points
    79
    Par défaut
    J'ai procédé de cette manière:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    int File::read(int lineNumber, int & sortie) throw(out_of_range) {
    	if(lineNumber >= (int) m_lines.size()) throw out_of_range("out of range");
    	try {
    		sortie =fromStringTo<int>(m_lines.at(lineNumber));
    	} catch(BadConversionError &e) {
    		cerr << "You must clean the file before reading." << " (int)"<< endl;
    		cerr << e.what();
    		return FAIL_READING_CONFIG;
    	}
            return SUCCESS_READING;
    }
     
    template<typename T>
    static T fromStringTo(string const& s, bool failIfLeftoverChars = true) throw(BadConversionError&){
    	T x;
    	istringstream i(s);
    	char c;
    	if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
    		throw BadConversionError(s);
    	return x;
    }
    Qu'en pensez-vous ?

  15. #15
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par white_tentacle Voir le message
    D'après ma page man, EINVAL n'est pas garanti... . Ca marche sur toutes les implémentations que tu connais ?
    endptr pointe vers la donnee en entree s'il n'y a pas eu de conversion et il faut ensuite tester errno si le resultat is LONG_MAX/MIN ).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

Discussions similaires

  1. Afficher une image en fonction de l'état d'une variable
    Par lcoulon dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 02/05/2011, 19h25
  2. Réponses: 5
    Dernier message: 29/07/2009, 09h00
  3. Réponses: 4
    Dernier message: 08/01/2007, 14h48
  4. Envoyer une variable dans un état
    Par uskiki85 dans le forum Access
    Réponses: 5
    Dernier message: 13/10/2005, 21h44
  5. tester l'état d'un bit d'une variable
    Par jphi5 dans le forum C
    Réponses: 5
    Dernier message: 15/09/2003, 13h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo