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 :

Programmation sous linux


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2012
    Messages : 4
    Par défaut Programmation sous linux
    Bonjour, alors voilà, je débute dans la programmation en C sous linux et je voulais savoir quelque chose, supposons qu'on a une boucle while à l'intérieur d'une autre boucle while, est-ce que c'est possible de sortir de la deuxième boucle, juste appuyant sur une touche sans utiliser scanf qui va à chaque fois nous arrêter pour nous demander si on veut continuer ou pas ?

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2011
    Messages
    1 255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 255
    Par défaut
    je ne suis pas un pro, mais je dirais peut-être en utilisant la fonction select avec le file descriptor représentant le clavier et un timeout très faible.

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 151
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    La bonne méthode consiste à ce que ta boucle while englobante possède un test de sortie adéquat.
    Ou d'utiliser un goto.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    bool bExit = false;
    while (condition1 && !bExit) {
     while (condition2) {
      // je veux quitter les 2 boucles
      bExit = true;
     }
    }
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2011
    Messages
    1 255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 255
    Par défaut
    Bousk, tu résous la partir la plus simple du problème.

    Quid de la saisie non bloquante de l'entrée clavier ?

    Utiliser un goto n'est pas déconnant non plus (avec modération, bien sûre). Si tu édites un code très fiable, au hasard, le noyau Linux, il y a pas mal de goto.

  5. #5
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Citation Envoyé par mala92 Voir le message
    Utiliser un goto n'est pas déconnant non plus (avec modération, bien sûre). Si tu édites un code très fiable, au hasard, le noyau Linux, il y a pas mal de goto.
    Le noyau linux est un code particulierement sale(*), qui n'est pas du tout a prendre en exemple.

    (*) Ceci n'est pas un troll, mais une verite, et s'explique tres bien, notamment a cause des contraintes du noyau.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Sous Linux, la manière la plus simple (non portable) de faire ça est avec poll()

    Voici un petit programme d'exemple :

    Code C : 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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    #ifndef SUCCESS
    #define SUCCESS 0
    #define ERROR 1
    #endif
     
     
    /*
     *  C h e c k s _ T o _ R e a d _ I n p u t
     *
     */
    static int  Checks_To_Read_Input ( void )
    {
       int             iret ;
       struct pollfd   fds[1] ;
     
       fds[0].events = POLLIN | POLLRDNORM ;
     
       fds[0].fd = fileno(stdin) ;
     
       /* Checks the state of the communication */
       iret = poll (fds, 1, 100 );
     
       if ( (iret <= 0) ||
    	(((! fds[0].revents & POLLIN) && (fds[0].revents & POLLRDNORM)) ||
    	 (fds[0].revents & POLLERR) || (fds[0].revents & POLLHUP)) )
           return ERROR ;
       else
           return SUCCESS ;
    }
     
     
    /*
     * Q u e s t i o n s
     *
     */
    static int Questions()
    {
      int  rep=0, n ;
      char c, buf[3] ;
     
      fprintf (stderr, "\n\n What would you like to do :\n");
      fprintf (stderr, "\n      1 : do some stuff");
      fprintf (stderr, "\n      2 : do other stuff");
      fprintf (stderr, "\n      .....");
      fprintf (stderr, "\n     50 : exit ");
      fprintf (stderr, "\n\n Please enter your choice : ");
      while ( Checks_To_Read_Input() == ERROR )
        {
        }
     
      n = 0 ;
      c = 0 ;
      while ( (c != '\n') || (c != 10) || (c != 13) )
        {
          fscanf ( stdin, "%c", &c );
          if ( (c != '\n') || (c != 10)|| (c != 13) )
            {
                buf[n] = c ;
                n = n + 1 ;
                if ( n == 2 )
                break ;
            }
        }
     
      if ( n == 0 )
        rep = Questions();
     
      sscanf ( buf, "%d", &rep );
     
      switch ( rep )
        {
            ....
        }
     
      return rep ;
    }
     
    /*
     * W a i t s _ F o r _ I n p u t
     *
     */
    static void Waits_For_Input( void )
    {
      int          s=0 ;
     
      while ( (s = Questions()) != 50 )
         {
            /* Do the processing */
         }
    }
     
    /*
     * Main program
     *
     */ 
    int main(int argc, char *argv[])
    {
      Waits_For_Input();
     
      return 0 ;
    }

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 151
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par mala92 Voir le message
    Quid de la saisie non bloquante de l'entrée clavier ?
    A vrai dire, je n'ai pas compris ce passage du post initial.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 484
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 484
    Par défaut
    Hello à tous !

    select() ou poll() sont indiqués lorsque l'on veut bloquer mais monitorer plusieurs choses à la fois. Et plus précisément, dans le cas qui nous intéresse, surveiller le clavier en plus de la tâche principale confiée à la boucle.

    Par contre, si la seule chose que l'on souhaite, c'est empêcher le clavier de bloquer la boucle (cas d'un calcul de longue durée, par exemple), ce qu'il faut faire, c'est ouvrir le fichier en mode non-bloquant avec O_NONBLOCK. Dans ce cas, là où un appel aurait bloqué en temps normal, il ressortira immédiatement avec l'erreur EAGAIN qu'il faudra surveiller. Cela dit, les appels systèmes ont quand même un coût et il est plus indiqué de ne tester le clavier que tous les n tours de boucle, par exemple.

    Pour appliquer ce flag à un descripteur déjà ouvert (comme l'entrée standard), il faut utiliser fcntl(). Voir ici : http://stackoverflow.com/questions/1...ock-vs-fionbio


    En ce qui concerne le fait de sortir d'une boucle, le booléen ne se justifie que si le cycle en cours doit impérativement être mené à terme avant de quitter la boucle, sinon un break suffit et il est tout aussi déterministe. Et en ce qui concerne le fait de sortir d'un coup de plusieurs boucles imbriquées, là, je préfère largement un goto à un booléen (modulo les même réserves). Sinon, il faut introduire des registres là où le problème aurait pu être résolu en amont et à la compilation. Malheureusement, l'habitude a tellement été prise de mettre à l'index le goto que plus personne ne peut se permettre de les utiliser là où ils auraient été le plus indiqué.

  9. #9
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Citation Envoyé par Threepwood_yume Voir le message
    Bonjour, alors voilà, je débute dans la programmation en C sous linux et je voulais savoir quelque chose, supposons qu'on a une boucle while à l'intérieur d'une autre boucle while, est-ce que c'est possible de sortir de la deuxième boucle, juste appuyant sur une touche sans utiliser scanf qui va à chaque fois nous arrêter pour nous demander si on veut continuer ou pas ?
    Salut,

    donc tu as quelquechose du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    while (condition1) {
      ...
      while (condition2) {
        ...
        if (interruption_boucle2) {
          afficher un état / demander si on poursuit / etc ...
        }
      }
      ...
    }
    Il y plusieurs moyens pour réaliser cela :

    * La solution préconisée par mala92 est simple à mettre en oeuvre et de plus te fera découvrir des techniques que tu pourras mettre en oeuvre dans d'autres problèmes (utilisation de socket, pipe et compagnie) ; tu es sous linux donc je suppose que tu utilises la gnu libc. Le manuel te donne un exemple pour réaliser ç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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    #include <errno.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/time.h>
     
    int input_timeout(int filedes, unsigned int seconds)
    {
      fd_set set;
      struct timeval timeout;
     
      /* Initialize the file descriptor set. */
      FD_ZERO(&set);
      FD_SET(filedes, &set);
     
      /* Initialize the timeout data structure. */
      timeout.tv_sec = seconds;
      timeout.tv_usec = 0;
     
      /* select returns 0 if timeout, 1 if input available, -1 if error. */
      return TEMP_FAILURE_RETRY(select(FD_SETSIZE,
               &set, NULL, NULL, &timeout));
    }
     
    int main(void)
    {
      fprintf(stderr, "select returned %d.\n",
        input_timeout(STDIN_FILENO, 5));
      return 0;
    }
    Tu peux facilement modifier cet exemple pour avoir une granularité de l'ordre de la microseconde en timeout. Imaginons que tu redéfinis input_timeout en :
    int input_timeout(int filedes, unsigned int seconds, unsigned int microsec)

    if (interruption_boucle2) pourra être remplacé par
    if (input_timeout(STDIN_FILENO,0,100)==1)

    À chaque tour de boucle tu "perds" 100 microsecondes à attendre une entrée, s'il y en a une de dispo on rentre dans le if, sinon on continue.
    Je pense que ce sera le plus simple pour toi si tu débutes (même si je suppose que tu ne vas tout comprendre mais il faut bien commencer quelquepart).

    Sinon il y a aussi (pour lecture) des solutions qui te font "perdre" moins de temps mais qui sont plus complexes à mettre en oeuvre.

    * Tu peux utiliser un signal, type SIGINT (=CTRL-c). À réception de ce signal tu peux demander quoi faire à l'utilisateur. cf le manuel.

    * Tu peux aussi utiliser un fork. Le processus père attend soit une entrée de l'utilisateur soit la terminaison du fils.

    * Tu peux carrément utiliser des threads (un peu comme le point précédent).

    Ces trois dernières solutions posent des problèmes quand plusieurs threads essayent d'accéder à des ressources communes.
    Mais c'est surtout pour te donner un aperçu de ce qui est faisable pour que tu puisses éventuellement y revenir par la suite quand tu auras acquis plus d'expérience.

Discussions similaires

  1. comment desinstaller un programme sous linux
    Par reg01 dans le forum Applications et environnements graphiques
    Réponses: 8
    Dernier message: 15/05/2007, 16h42
  2. Réponses: 1
    Dernier message: 16/04/2007, 13h56
  3. Faire fonctionner des programmes sous Linux
    Par vviivvii dans le forum Mandriva / Mageia
    Réponses: 14
    Dernier message: 29/08/2006, 19h41
  4. [16F84a] Programmation sous linux
    Par Michaël dans le forum Autres architectures
    Réponses: 2
    Dernier message: 25/02/2006, 12h05
  5. GDB/Recherche EDI - Debugguer un programme sous linux
    Par Rodrigue dans le forum Applications et environnements graphiques
    Réponses: 6
    Dernier message: 17/01/2006, 23h35

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