1. #1
    Membre à l'essai Avatar de beau_g
    Homme Profil pro
    Étudiant
    Inscrit en
    juillet 2017
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : juillet 2017
    Messages : 26
    Points : 24
    Points
    24

    Par défaut Message avant la boucle while(1)

    Bonjour a tous,

    Question facile :
    J'aimerai creer un programme qui lorsqu'on appuie sur 's', une fonction se lance dans une , lorqu'on appuie sur 'q' on quitte la boucle et sinon lorsque la lettre est differente, la fonction renvoie le message "veuillez reessayer" et la boucle redemarre

    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
    32
    33
    34
    35
    36
    37
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <pthread.h>
    #include "unicast_socket_sendto.h"
     
    int main(void) {
     
    	puts("!!!test 7!!!"); /* prints !!!Hello World!!! */
    	char *dest_ip = "127.0.0.1";
    	char *message = "hello";
    	int port = 7;
     
    	printf("Tape a letter S or Q:");
    	while (1){
     
    		char c = getchar();
     
    		if ((c=='s')||(c=='S'))
    		{
    			printf("Message sent: %s\n", message);
    			unicast_socket_sendto(port, dest_ip, message);
    			system("BREAK");
    			return EXIT_SUCCESS;
    		}
    		else if ((c=='q')||(c=='Q'))
    		{
    			printf("QUIT\n");
    			break;
    		}
    		else {
    			printf("Invalid key, tape 'S' to send a message, 'Q' to exit");
    				}
    	}
     
    }
    Dans mon programme, j aimerai que le message "Tape a letter S or Q" apparaisse avant de rentrer la lettre, or ce n est pas le cas, et reapparraisse pour la derniere condition. Pouvez vous m'aider svp

    Merci pour vos reponses

    Bien a vous,

    Beaug.

  2. #2
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    décembre 2013
    Messages
    116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : décembre 2013
    Messages : 116
    Points : 99
    Points
    99

    Par défaut

    Mais en commentaire puts("!!!test 7!!!"); /* prints !!!Hello World!!! */
    ou simplement remplace la fonction puts par printf

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    5 850
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : février 2006
    Messages : 5 850
    Points : 16 117
    Points
    16 117
    Billets dans le blog
    1

    Par défaut

    Bonjour

    Citation Envoyé par beau_g Voir le message
    j aimerai que le message "Tape a letter S or Q" apparaisse avant de rentrer la lettre, or ce n est pas le cas
    Rajoute fflush(stdout) juste en dessous de ton printf("Tape a letter S or Q:").

    Citation Envoyé par beau_g Voir le message
    et reapparraisse pour la derniere condition.
    Là je ne pige pas. Mais si tu veux que ton message "Tape a letter S or Q" soit affiché à chaque itération, il te faut alors le mettre dans le while.
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  4. #4
    Membre expérimenté

    Homme Profil pro
    Responsable des études
    Inscrit en
    mars 2009
    Messages
    536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : Industrie

    Informations forums :
    Inscription : mars 2009
    Messages : 536
    Points : 1 532
    Points
    1 532

    Par défaut

    Pour compléter la réponse de Sve@r, il est courant que printf soit implémenté avec une mémoire tampon.
    Cette mémoire tampon n'est transmise à l'écran que lorsqu'elle est suffisamment remplie, ou bien si on demande explicitement que le transfert ait lieu.
    Pour ce dernier cas, il y a effectivement la fonction fflush, mais généralement un retour à la ligne fait l'affaire.

    Donc tu peux essayer de te passer de fflush en faisant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("Tape a letter S or Q:\r\n");

  5. #5
    Membre expérimenté

    Homme Profil pro
    Responsable des études
    Inscrit en
    mars 2009
    Messages
    536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : Industrie

    Informations forums :
    Inscription : mars 2009
    Messages : 536
    Points : 1 532
    Points
    1 532

    Par défaut

    Accessoirement, suivant le contexte, "tape" en anglais signifie "scotcher" ou "enregistrer sur cassette"...
    Je pense que tu voulais dire "hit" or "push" !

  6. #6
    Membre à l'essai Avatar de beau_g
    Homme Profil pro
    Étudiant
    Inscrit en
    juillet 2017
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : juillet 2017
    Messages : 26
    Points : 24
    Points
    24

    Par défaut

    Bonjour à tous,

    Merci pour vos réponses, ça marche comme je voudrai maintenant !

    Sauf un détail lorsque la dernière condition est activée, le programme boucle 2 fois...

    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
    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
    include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <pthread.h>
    #include "unicast_socket_sendto.h"
     
     
     
    void *send_uni(void *arg)
    	{
    	char *dest_ip = "127.0.0.1";
    	char *message = "hello";
    	int port = 7;
     
     
    	while (1)
    	{
     
    		printf("Push a letter S or Q:\r\n ");
    		char c = getchar();
     
    		if ((c=='s')||(c=='S'))
    		{
    			printf("Message sent: %s\n", message);
    			unicast_socket_sendto(port, dest_ip, message);
    			system("BREAK");
    			return EXIT_SUCCESS;
    		}
    		else if ((c=='q')||(c=='Q'))
    		{
    			printf("QUIT");
    			break;
    		}
    		else
    		{
    			printf("Invalid key, tape 'S' to send a message, 'Q' to exit.");
    		}
    	}
     
    	return NULL;
    }
     
     
    int main(void)
    {
    	/* this variable is our reference to the second thread */
    	pthread_t thread;
     
    	/* create a second thread which executes send_uni(void *arg) */
     
    	if(pthread_create(&thread, NULL, send_uni, NULL)) {
    		fprintf(stderr, "Error creating thread\n");
    		return 1;
    	}
     
    	/* wait for the second thread to finish */
    	if(pthread_join(thread, NULL)) {
    		fprintf(stderr, "Error joining thread\n");
    		return 2;
    	}
    	return 0;
    }
    Le message voulu apparait donc 2 fois

    Nom : Capture.PNG
Affichages : 44
Taille : 3,6 Ko

    Aussi, je ne sais pas si le problème viens de mon ordinateur ou de mon programme, mais lorsque je ''run'' le programme sur eclypse IDE, mon PC crash avec "Ecran bleu"...ça me rend fou ^^'
    Cela vous est déjà arrivé ?

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2005
    Messages
    26 477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2005
    Messages : 26 477
    Points : 38 213
    Points
    38 213

    Par défaut

    C'est parce que tu tapes deux caractères: La lettre 'g', et la touche Entrée ('\n').
    Ce qui t'intéresse, c'est le premier caractère de la ligne tapée au clavier; tu peux donc utiliser cette fonction après ton getchar():
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    /*Returns 0 if OK, a negative value if EOF.*/
    int fpurge(FILE *f)
    {
    	int c;
    	while((c=fgetc(f))!=EOF && c!='\n')
    	{ }
    	return (c==EOF ? -1 : 0);
    }

    Employée ainsi:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    		char c = getchar();
    		fpurge(stdin);
    Cela prendra le premier caractère de la ligne dans la variable c, puis fera passer tous les caractère suivants de la même ligne (y compris le '\n') à la trappe.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    5 850
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : février 2006
    Messages : 5 850
    Points : 16 117
    Points
    16 117
    Billets dans le blog
    1

    Par défaut

    Medinoc propose une solution basée sur la purge du buffer input. Perso je reste très méfiant sur son utilisation "à outrance" parce que généralement, si stdin possède des infos, c'est qu'elles y ont été mises pour une bonne raison qui mérite qu'on s'y intéresse plutôt que de les jeter. Surtout que ce buffer n'est pas forcément rattaché au clavier. En effet, dans le monde posix il existe un outil de communication inter programmes nommé "pipe" dans lequel on demande explicitement à lier via un tube deux programmes P1 et P2. A ce moment là, tout ce qui est "output" de P1 part dans le tube et tout ce qui est "input" de P2 est pris depuis le tube. Mais P1 et P2 n'ont pas connaissance de ce fait. Eux ils continuent à écrire dans "stdout" et à lire depuis "stdin". Simplement "stdout" et "stdin" ont été redéfinis par l'OS comme étant les deux cotés du tube. Et si le programmeur de P2 prend l'habitude de purger stdin parce qu'il ne le maitrise pas, son programme partira dans le décors dès qu'il sera lié à un pipe.

    Mais c'était bien quand-même qu'il te montre cette option parce qu'ici ça se justifie. Son analyse est bonne. Quand tu tapes "g", tu n'en as pas conscience mais tu tapes sur 2 touches de ton clavier: le 'g' et le <return> (symbolisé par '\n'). Ben ces deux touches sont alors stockées dans stdin. Ensuite à la première itération le getchar() lit le 'g' et il lit le '\n' à la seconde. Et si tu avais tapé "toto" au lieu de "g" ben ton programme aurait bouclé 5 fois au lieu de 2.

    Et ce problème apparaitra de plus en plus quand tu voudras faire de la saisie diverses (chiffres puis mot puis flottant etc). Tu saisis ton chiffre, tu finis par '\n', ensuite le programme arrive à la saisie du mot et là il lit le '\n' (donc toi tu te retrouves devant un programme qui ne s'arrête pas pour te faire saisir le mot), etc etc etc.

    Donc dans les cas où la purge n'est pas possible, alors une autre possibilité est de passer par fgets() (lire donc tout ce qui a été tapé ce qui le supprime de stdin) puis traiter ce qui a été lu (généralement via sscanf() qui fonctionne comme scanf() à ceci près que les infos sont récupérées depuis une string et non depuis stdin)
    Exemple dans ton cas
    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
    while (1)
    {
    	printf("Push a letter S or Q:\r\n ");
    	char saisie[256];
    	fgets(saisie, 256, stdin);
    	char c=saisie[0];
     
    	if ((c=='s')||(c=='S'))
    	{
    		printf("Message sent: %s\n", message);
    		unicast_socket_sendto(port, dest_ip, message);
    		system("BREAK");
    		return EXIT_SUCCESS;
    	}
    	if ((c=='q')||(c=='Q'))
    	{
    		printf("QUIT");
    		break;
    	}
    	printf("Invalid key, tape 'S' to send a message, 'Q' to exit.");
    }

    Ce n'est pas encore parfait (si l'utilisateur tape 500 lettres je n'en lis que 255 donc il en reste 245 qui seront lues à l'itération suivante) mais pour un petit code lambda ça suffit. Et si tu veux écrire un code plus robuste, alors t'as encore d'autres possibilités.

    Désolé pour ton écran bleu zindow quand tu lances ton code par Eclipse. Je te proposerais bien d'envisager éventuellement de passer sous Linux.. Sinon tu peux essayer de commenter la ligne unicast_socket_sendto(port, dest_ip, message). C'est la seule de ton code qui me semble un peu exotique et qui pourrait alors être "trop" exotique pour Eclipse...

    PS: tu auras remarqué l'économie de tabulations dans les tests de la lettre tapée. Ben oui, si tu quittes la boucle sur un "if", pas la peine de mettre la suite dans un "else" car cette partie ne sera traitée que si tu n'as pas quitté la boucle. Ceci dit, c'est très malvenu de quitter une fonction via exit(). La politesse veut que si A() appelle B(), alors B() doit se terminer pour que A() continue son travail. Et si A() ne peut plus continuer suite à une défaillance de B() alors il s'arrête lui-aussi et on remonte ainsi la défaillance de niveau en niveau jusqu'à ce qu'on tombe soit sur une fonction qui sait la gérer, soit jusqu'au main() qui, lui, aura alors le droit de quitter le programme.
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2005
    Messages
    26 477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2005
    Messages : 26 477
    Points : 38 213
    Points
    38 213

    Par défaut

    Ce n'est pas une purge de toute l'entrée, mais seulement du reste de la ligne courante.
    Quand on demande une entrée ligne par ligne avec un seul caractère, soit on ignore le reste, soit on gueule dès qu'il y a plus d'un caractère. La seconde solution est possible, mais dans tous les cas, dans l'exemple courant on n'a jamais besoin du reste de la ligne.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. boucle while trop lente
    Par atouze dans le forum Access
    Réponses: 17
    Dernier message: 15/06/2005, 16h35
  2. Boucle while & read
    Par gibet_b dans le forum Linux
    Réponses: 4
    Dernier message: 29/04/2005, 15h38
  3. boucle while et post incrémentation
    Par tut dans le forum C++
    Réponses: 7
    Dernier message: 10/12/2004, 17h24
  4. [MFC] Dialog dans une boucle while
    Par oxor3 dans le forum MFC
    Réponses: 5
    Dernier message: 23/04/2004, 22h51
  5. [débutant]Documentation? boucle "while"? Session?
    Par o151181 dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 19/01/2004, 15h20

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