Basculer entre les instructions si l’utilisateur entre quelque chose: infiniment et avec un délai d’attente

Pour expliquer plus clairement ce que je veux faire, je veux que mon code vérifie si l’utilisateur entre quelque chose (ou si un autre descripteur de fichier que 0 a des données à lire) toutes les (disons) toutes les 2,5 secondes et ainsi jusqu’à ce que le programme s’arrête.

Si l’utilisateur entre quelque chose, un simple printf() le notifiera et le programme vérifiera à nouveau si l’utilisateur entre quelque chose dans les 2,5 prochaines secondes.

Sinon, il faut simplement indiquer que le temps s’est écoulé, puis vérifier à nouveau la saisie de l’utilisateur dans les 2,5 prochaines secondes.

Et voici l’extrait de code que j’ai volé du Guide de la programmation réseau de Beej et modifié pour (essayer de) répondre à mes exigences:

 #include  #include  #include  #include  #define STDIN 0 // file descriptor for standard input int main(void){ struct timeval tv; fd_set readfds; FD_ZERO(&readfds); FD_SET(STDIN, &readfds); tv.tv_sec = 2; tv.tv_usec = 500000; while(1){ select(STDIN+1, &readfds, NULL, NULL, &tv); if (FD_ISSET(STDIN, &readfds)){ printf("A key was pressed!\n"); tv.tv_sec = 2; tv.tv_usec = 500000; }else{ printf("Timed out.\n"); tv.tv_sec = 2; tv.tv_usec = 500000; } } return 0; } 

Tant que je n’appuie sur aucune touche, cela fonctionne bien et affiche “Expiré”. toutes les 2,5 secondes. Mais si j’entre quelque chose, il semble ignorer la saisie de l’utilisateur et continue à imprimer “Expiré”.

D’autre part, si je déclare le fd_set et la struct timeval à l’ intérieur de la boucle infinie, une fois que j’entre quelque chose, cela indique infiniment qu’une touche a été enfoncée comme si elle ignorait le délai.

Je ne sais pas pourquoi un code aussi simple ne fonctionne pas. J’imagine qu’il me manque un élément concernant les descripteurs de fichier que je ne connais pas.

Parce que vous devez réinitialiser -> FD_ZERO(&readfds) vos readfds et append le fichier desciptor -> FD_SET(STDIN, &readfds) chaque fois que la commande retourne est retournée, car le descripteur de fichier est supprimé de l’ensemble

 #include  #include  #include  #include  #define STDIN 0 // file descriptor for standard input int main(void){ struct timeval tv; fd_set readfds; while (1) { int count; /* how many descriptors are contained in the set. */ FD_ZERO(&readfds); FD_SET(STDIN, &readfds); tv.tv_sec = 2; tv.tv_usec = 500000; count = select(STDIN + 1, &readfds, NULL, NULL, &tv); if ((count > 0) && (FD_ISSET(STDIN, &readfds) != 0)) { printf("A key was pressed!\n"); } else if (count == -1) /* check for the error here */ } else { printf("Timed out.\n"); } } return 0; } 

comme vous le voyez, vous devriez également vérifier la valeur de retour de select , pour rechercher une erreur, en cas d’erreur, puis vérifier errno pour voir ce qui s’est passé, puis vérifier que le descripteur de fichier qui vous intéresse est contenu dans readfds .