Menu

Passage difficile d,une boucle

Leer0r 22 Messages postés vendredi 22 décembre 2017Date d'inscription 26 juin 2018 Dernière intervention - 8 mai 2018 à 14:05 - Dernière réponse : Leer0r 22 Messages postés vendredi 22 décembre 2017Date d'inscription 26 juin 2018 Dernière intervention
- 26 mai 2018 à 00:55
Bonjour,
Dans le cadre de mon projet en ISN, je dois réaliser un distributeur de boisson chaude. Pour rendre le tout plus réaliste, j,ai créé un texte défilant au début, le problème étant de passer de ce dernier au menu principal. Le texte défilant étant dans une boucle, je ne sais pas comment faire pour passer a la boucle suivante juste avec un appuis sur une touche.

Merci d,avance
Afficher la suite 

Votre réponse

15 réponses

Meilleure réponse
aure2015 72 Messages postés dimanche 11 janvier 2009Date d'inscription 15 juin 2018 Dernière intervention - 8 mai 2018 à 15:22
1
Merci
Salut!

Donc tu veux attendre après ta boucle que l'utilisateur puisse lire le texte défilant avant de passer au menu principal, c'est bien ça?

Simplement avec getchar si j'ai bien compris ce que tu voulais!


while(!QUITTER)
{
	//Menu principal
	
	while(...) //Fin menu défilant
	{
	
	}
	
	printf("Appuyer sur une touche pour continuer");
	fflush(stdin); //On vide le buffer!
	getchar(); // On attend que l'utilisateur appuye sur une touche!
}


Merci aure2015 1

Avec quelques mots c'est encore mieux Ajouter un commentaire

CCM a aidé 25075 internautes ce mois-ci

[Dal] 4747 Messages postés mercredi 15 septembre 2004Date d'inscriptionContributeurStatut 17 octobre 2018 Dernière intervention - 9 mai 2018 à 10:30
voulais-tu écrire
fflush(stdout);
?
Commenter la réponse de aure2015
Meilleure réponse
[Dal] 4747 Messages postés mercredi 15 septembre 2004Date d'inscriptionContributeurStatut 17 octobre 2018 Dernière intervention - Modifié par [Dal] le 9/05/2018 à 09:44
1
Merci
Salut Leer0r,

Sous Windows, tu peux utiliser
_kbhit()
, accessible par l'entête
conio.h
pour tester si une touche a été appuyée sans interrompre l'exécution du programme.

https://msdn.microsoft.com/fr-fr/library/58w7c94c.aspx
https://c.developpez.com/faq/?page=Gestion-du-clavier-et-de-l-ecran-en-mode-console#Comment-intercepter-une-touche-sans-bloquer-le-programme-DOS-Windows

Sous Linux, tu as une bibliothèque ncurses qui permet de disposer d'une fonction équivalente, ou tu peux simuler cela de différentes façons avec le terminal :

https://c.developpez.com/faq/?page=Gestion-du-clavier-et-de-l-ecran-en-mode-console#Comment-simuler-la-fonction-kbhit-sous-UNIX
https://c.developpez.com/faq/?page=Gestion-du-clavier-et-de-l-ecran-en-mode-console#Comment-faire-passer-un-terminal-en-mode-brut-UNIX

Dal

Merci [Dal] 1

Avec quelques mots c'est encore mieux Ajouter un commentaire

CCM a aidé 25075 internautes ce mois-ci

[Dal] 4747 Messages postés mercredi 15 septembre 2004Date d'inscriptionContributeurStatut 17 octobre 2018 Dernière intervention - 9 mai 2018 à 10:33
avec ncurses, on utiliserait getch() en mode no-delay pour détecter la pression d'une touche sans bloquer le programme

http://invisible-island.net/ncurses/man/curs_inopts.3x.html
http://invisible-island.net/ncurses/man/curs_getch.3x.html
Commenter la réponse de [Dal]
Leer0r 22 Messages postés vendredi 22 décembre 2017Date d'inscription 26 juin 2018 Dernière intervention - 8 mai 2018 à 15:39
0
Merci
oui c,est cette boucle qui continu a l,infini ^^" je dois donc mettre le getchar() a la fin de cette dernière ?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined WIN32 || defined WIN64
#        include <windows.h>
#        define sleep(x) Sleep(1000 * (x))
#else
#        include <unistd.h>
#endif
static void
scroll(char const *s)
{
    char const *p;
    for (p = s + strlen(s); p != s; p--) {
        char const *q;
        for (q = p; *q != '\0'; q++)
            putchar(*q);
        for (q = s; q != p; q++)
            putchar(*q);
        putchar('\r');
        fflush(stdout);
        sleep(0.1);
    }
}
int
main(void)
{
    char const *s = "           BIENVENU AU DISTRIBUTEUR DE BOISSON CHAUDE !                        ";
    while (1)
        scroll(s);
    return EXIT_SUCCESS;
}
aure2015 72 Messages postés dimanche 11 janvier 2009Date d'inscription 15 juin 2018 Dernière intervention - 8 mai 2018 à 16:08
Ah je comprends!

Non si tu mets un getchar() après ta boucle ça va devoir attendre que l'utilisateur encode une touche bien sûr!

Tu connais un peu les threads?
aure2015 72 Messages postés dimanche 11 janvier 2009Date d'inscription 15 juin 2018 Dernière intervention - 8 mai 2018 à 18:40
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>

#define QUITTER -1

void fctBoucleTexte (void *p);
pthread_t threadBoucleTxt;

int main()
{
    int choix;
    pthread_create(&threadBoucleTxt, NULL,(void*(*)(void*)) fctBoucleTexte, &NULL);
 
 while(!QUITTER)
 {
  //Menu
  
  choix=BouttonAppuye();
  
  switch(choix)
  {
   case choix1: //Choix 1
     break;
   case choix2: //Choix 2
     break;
   case choix3: //Choix 3
     break;
   //etc
  }
 }
 
 exit(0);
    
}


void fctBoucleTexte (void * p)
{
    while (1)
        scroll(s);
}

[Dal] 4747 Messages postés mercredi 15 septembre 2004Date d'inscriptionContributeurStatut 17 octobre 2018 Dernière intervention - 9 mai 2018 à 14:41
@LeerOr: sous Linux/Unix, le prototype de
sleep()
est
unsigned int sleep(unsigned int seconds);
, et la fonction ne peut donc pas prendre en paramètre un nombre à virgule. Du coup, C passera 0 à sleep() sous Unix, du fait de la promotion de type opérée, et tout se passera comme si tu n'avais pas définit de temporisation entre chaque itération.

Une fonction POSIX avec une résolution plus fine est nanosleep

http://man7.org/linux/man-pages/man2/nanosleep.2.html

@aure2015: les threads sont une bonne idée si le but est que le défilement continue pendant l'exécution du programme (et pas uniquement jusqu'à la pression d'une touche avant l'affichage du menu). A mon sens, alors, des fonctions additionnelles de gestion de la console permettant l'affichage du texte défilant à une position donnée de l'écran (du type
gotoxy()
) deviendraient aussi nécessaires, sinon, on va se trimbaler les affichages gênants sur tout l'écran à chaque mouvement du curseur :-)

du coup, l'usage de ncurses se justifierait aussi, pour éviter d'avoir à bricoler avec les séquences d'échappement POSIX.

pthread est POSIX, ils sont portés sous Windows https://sourceware.org/pthreads-win32/, ou, alors, il y a, bien sûr, les threads Windows https://msdn.microsoft.com/en-us/library/windows/desktop/ms682516%28v=vs.85%29.aspx qui ne sont pas forcément évidents.

puisque Leer0r a l'air de vouloir faire un programme portable, il y a des choix à faire, cela dit, cela commence à faire beaucoup pour un projet ISN, et une complexité qui ne se justifie peut-être pas juste pour faire un truc qui défile :-)
Commenter la réponse de Leer0r
Leer0r 22 Messages postés vendredi 22 décembre 2017Date d'inscription 26 juin 2018 Dernière intervention - 17 mai 2018 à 12:20
0
Merci
Merci beaucoup pour vos réponses et désolée du retard de celle là, assimiler tout ça n'a pas été facile ^^"" donc oui mon but est de faire une boucle avec le texte défilant qui continue tant que l'utilisateur n'appuie pas sur une touche ^^

@[Dal] tu disais que le
_kbhint
servait à tester si une touche avait été appuillée mais elle n'est pas utile si je veut que l'utilisateur passe au menu principal en appuyant sur n'importe quelle touche non ?

Du coup
getch ()
est utile pour ce problème ?

Je n'ai pas encore pu regarder pour POSIX @[Dal] mais je ne comprends pas vraiment son utilité^^""
Leer0r 22 Messages postés vendredi 22 décembre 2017Date d'inscription 26 juin 2018 Dernière intervention - 22 mai 2018 à 20:27
@[Dal]
j,ai essayer le code que tu m,a donné et lorsque j,appuis sur une touche ça bloque juste le texte défilant ^^"""
J,ai maintenant le code complet que voici :
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "chose a int.h" //dans un fichier d,en tête j,ai mis tout les trucs a int pour plus de lisibilitée 
#if defined WIN32 || defined WIN64
#        include <windows.h>
#        define sleep(x) Sleep(1000 * (x))
#else
#        include <unistd.h>
#endif


static void scroll(char const *s) {
	char const *p;

	while (1) {
		for (p = s + strlen(s); p != s; p--) {
			char const *q;
			for (q = p; *q != '\0'; q++)
				putchar(*q);
			for (q = s; q != p; q++)
				putchar(*q);
			putchar('\r');
			fflush(stdout);
			if (_kbhit())
				return ;
			Sleep(DWORD(1000 * (0.1)));
			
		}
	}
}
 

int
main(void)
{
	char const *s = "           BIENVENU AU DISTRIBUTEUR DE BOISSONS CHAUDES !                        ";

	while (1) 
	{
		scroll(s);
	}

	return 0;
}

int main(void)
	{
		while (i != 'q')
		{
			printf(" \t -----------------------Menu Principal-----------------------\n");
			printf("\t\t\t  | Nous vous proposons :\n");
			printf("\n\t\t\t| - CAFE NOIR          <N>|");
			printf("\n\t\t\t| - CAFE AU LAIT       <L>|");
			printf("\n\t\t\t| - THE CHAUD          <T>|");
			printf("\n\t\t\t| - CHOCOLAT au LAIT   <C>|");
			printf("\n\t\t\t| - SOUPE CHAUDE       <S>|");
			printf("\n\t\t\t| - LAIT CHAUD         <B>|\n");
			printf("\t ------------------------------------------------------------\n");
			i = getch();
			switch (i)
			{
			case'N':
			case'n': printf("\nVous avez choisis du CAFE NOIR !\n");
				break;
			case'L':
			case'l': printf("\nVous avez choisis du CAFE AU LAIT !\n");
				break;
			case'T':
			case't': printf("\nVous avez choisis du THE CHAUD !\n");
				break;
			case'C':
			case'c': printf("\nVous avez choisis du CHOCOLAT au LAIT !\n");
				break;
			case'S':
			case's': printf("\nVous avez choisis de la SOUPE CHAUDE !\n");
				break;
			case'B':
			case'b': printf("\nVous avez choisis du LAID CHAUD !\n");
				break;

			}
			if (i != 'q')
			{
				printf("PRIX=1EURO (2e:[z] 1e:[e] | 0.5e:[r] | 0.2e:[t] | 0.1e:[y] )\n");
				while ((prix<1) && (i != 'q'))
				{
					i = getch();
					switch (i)
					{
					case'z': prix = prix + 2;
						break;
					case'e': prix = prix + 1;
						break;
					case'r': prix = prix + 0.5;
						break;
					case't': prix = prix + 0.2;
						break;
					case'y': prix = prix + 0.1;
					}
				}
			}

			if (prix>1)
			{
				rendu = prix - 1;
			}

			if (i != 'q')
			{
				prix = 0;
				printf("\n paiement accepte \n");
				sleep(2);
				printf("\n debut de la preparation de la boisson\n \n");
				sleep(1.5);
				while (n>0)
				{
					n--;
					printf("il reste %d seconde", n);
					sleep(1);
					printf("\x0d");

				}

				rendu = prix;
				printf("\nRendu %feuro\n", rendu);
				printf("\nVeuillez prendre votre boisson!\n\n");
			}

			sleep(6);
			system("cls");
		}
	}

ai-je une erreur qui traîne car maintenant le texte défilant ne s,affiche même plus et le programme commence directement au menu principal ^^""
[Dal] 4747 Messages postés mercredi 15 septembre 2004Date d'inscriptionContributeurStatut 17 octobre 2018 Dernière intervention - 23 mai 2018 à 12:12
comme ta boucle infinie gérant le défilement est désormais dans scroll(), tu peux la retirer de main() où tu fais juste, par exemple :

int main(void)
{
 char const *s = "           BIENVENUE AU DISTRIBUTEUR DE BOISSONS CHAUDES !                        ";
 scroll(s);
 int i = '\0';
 while (i != 'q') {
  printf(" \t -----------------------Menu Principal-----------------------\n");
  (...)

Note que dans un programme C tu ne peux avoir qu'une seule fonction main(), qui est le point d'entrée de l'exécution de ton programme (là tu en as deux, dont une qui contient la suite de ton code, et qui ne se termine pas par
return 0;
).

Je n'ai pas pu tester ton programme, étant sous Linux.

Comme tu utilises des fonctions conio.h comme getch(), qui ne sont pas présentes dans <unistd.h> et des
system("cls");
qui ne donneront un résultat que sous Windows, tu sembles finalement décider de faire un programme pour Windows seulement. Si oui, conserver ces directives de compilation :

#if defined WIN32 || defined WIN64
#        include <windows.h>
#        define sleep(x) Sleep(1000 * (x))
#else
#        include <unistd.h>
#endif

n'a pas trop de sens, et tu ne devrais mettre que
#include <windows.h>
à la place et faire tes appels à la fonction
Sleep()
et non
sleep()
dans ton code.

Ou garde
#include <windows.h>
et
#define sleep(x) Sleep(1000 * (x))
si tu veux et tes appels à
sleep()
pour t'éviter de taper des microsecondes ou le calcul des microsecondes à chaque appel.

il y a aussi "LAID" au lieu de "LAIT" :-D

Le code que tu postes ne contient pas les déclarations et initialisations de certaines variables qu'il utilise (i, n, prix etc.). Comme tu inclues
#include "chose a int.h" //dans un fichier d,en tête j,ai mis tout les trucs a int pour plus de lisibilitée
je suppose que c'est là que tu le fais.

Ce n'est pas exactement l'usage recommandé d'un fichier d'entête (vois http://umich.edu/~eecs381/handouts/CHeaderFileGuidelines.pdf pour de bonnes explications sur ce qui devrait figurer dans un .h et ce qui ne le devrait pas).

Le reste de ton code n'est pas clair, tu n'affectes pas un prix en fonction de la boisson choisie, tu utilises la variable prix pour compter le montant payé en pièces, tu calcule rendu, mais tu écrases sa valeur,... il faudra déboguer et peaufiner tout cela :-)

Dal
Leer0r 22 Messages postés vendredi 22 décembre 2017Date d'inscription 26 juin 2018 Dernière intervention - 25 mai 2018 à 20:14
Effectivement @[Dal]
void scroll(char const *s)
{

	{
		char const *p;

		for (p = s + strlen(s); p != s; p--) {
			char const *q;

			/* affiche ce qu'il y a à droite de p */
			for (q = p; *q != '\0'; q++)
				putchar(*q);

			/* affiche ce qu'il y a à gauche de p */
			for (q = s; q != p; q++)
				putchar(*q);

			putchar('\r');
			fflush(stdout);
			if (_kbhit())
				return;
			sleep(0.1);

		}
	}
}


	int main(void)
	{
		
		int i = '\0';
		while (i != 'q')
		{
			char const *s = "           BIENVENU AU DISTRIBUTEUR DE BOISSON CHAUDE !                        ";
			scroll(s);


ça marche enfin ^^ j,arrive a passer a la boucle suivante ^^ c,est vrai que c,etait un peu con mais merci beaucoup ^^

Comme tu utilises des fonctions conio.h comme getch(), qui ne sont pas présentes dans <unistd.h> et des system("cls"); qui ne donneront un résultat que sous Windows, tu sembles finalement décider de faire un programme pour Windows seulement
il est vrai ^^ j,ai raccourcis le code ^^

il y a aussi "LAID" au lieu de "LAIT" :-D
Oups oui ^^""

Le code que tu postes ne contient pas les déclarations et initialisations de certaines variables qu'il utilise (i, n, prix etc.). Comme tu inclues #include "chose a int.h" //dans un fichier d,en tête j,ai mis tout les trucs a int pour plus de lisibilitée je suppose que c'est là que tu le fais.

Ce n'est pas exactement l'usage recommandé d'un fichier d'entête

Notre prof nous a utilisée a introduire les variables dans un fichier d,en tête pour ce projet ^^ il est vrai qu,il peut être mieux utiliser mais bon on fait avec ce que l,on a ^^""

tu utilises la variable prix pour compter le montant payé en pièces, tu calcule rendu, mais tu écrases sa valeur,... il faudra déboguer et peaufiner tout cela :-)
oui j,ai régler ça j,avais complètement oublier de le faire désolé ^^"" mais j,ai un autre petit soucis qui se trouve être que lord de la réinitialisation du programme il me remet non pas au message défilant mais comme si j,avais déjà payer ma boisson ^^"" Cela devrait être la dernière chose qui pose soucis ^^""" est ce a cause de mes variables ?

Leer0r
[Dal] 4747 Messages postés mercredi 15 septembre 2004Date d'inscriptionContributeurStatut 17 octobre 2018 Dernière intervention - 25 mai 2018 à 21:05
au sujet de ton dernier problème, poste ton code corrigé pour qu'on y voit plus clair.
Leer0r 22 Messages postés vendredi 22 décembre 2017Date d'inscription 26 juin 2018 Dernière intervention - 26 mai 2018 à 00:55
@[Dal]
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "fichier-int.h"
#include <windows.h>
#define sleep(x) Sleep(1000 * (x))




void scroll(char const *s)
{

 {
  char const *p;

  for (p = s + strlen(s); p != s; p--) {
   char const *q;

   /* affiche ce qu'il y a à droite de p */
   for (q = p; *q != '\0'; q++)
    putchar(*q);

   /* affiche ce qu'il y a à gauche de p */
   for (q = s; q != p; q++)
    putchar(*q);

   putchar('\r');
   fflush(stdout);
   if (_kbhit())
    return;
   sleep(0.1);

  }
 }
}


 int main(void)
 {
  
  int i = '\0';
  while (1)
  {
   char const *s = "           BIENVENU AU DISTRIBUTEUR DE BOISSON CHAUDE !                        ";
   scroll(s);


   printf(" \t -----------------------Menu Principal-----------------------\n");
   printf("\t\t\t  | Nous vous proposons :\n");
   printf("\n\t\t\t| - CAFE NOIR          <N>|");
   printf("\n\t\t\t| - CAFE AU LAIT       <L>|");
   printf("\n\t\t\t| - THE CHAUD          <T>|");
   printf("\n\t\t\t| - CHOCOLAT au LAIT   <C>|");
   printf("\n\t\t\t| - SOUPE CHAUDE       <S>|");
   printf("\n\t\t\t| - LAIT CHAUD         <B>|\n");
   printf("\t ------------------------------------------------------------\n");
   p = getch();
   switch (p)
   {
   case'N':
   case'n': printf("\nVous avez choisis du CAFE NOIR !\n");
    break;
   case'L':
   case'l': printf("\nVous avez choisis du CAFE AU LAIT !\n");
    break;
   case'T':
   case't': printf("\nVous avez choisis du THE CHAUD !\n");
    break;
   case'C':
   case'c': printf("\nVous avez choisis du CHOCOLAT au LAIT !\n");
    break;
   case'S':
   case's': printf("\nVous avez choisis de la SOUPE CHAUDE !\n");
    break;
   case'B':
   case'b': printf("\nVous avez choisis du LAID CHAUD !\n");
    break;

   }
   if (i != 'q')
   {
    printf("PRIX=1EURO (2e:[z] 1e:[e] | 0.5e:[r] | 0.2e:[t] | 0.1e:[y] )\n");
    while ((prix<1) && (i != 'q'))
    {
     p = getch();
     switch (p)
     {
     case'z': prix = prix + 2;
      break;
     case'e': prix = prix + 1;
      break;
     case'r': prix = prix + 0.5;
      break;
     case't': prix = prix + 0.2;
      break;
     case'y': prix = prix + 0.1;
     }
    }
   }

   if (i != 'q')
   {
    
    printf("\n paiement accepte \n");
    sleep(2);
    printf("\n debut de la preparation de la boisson\n \n");
    sleep(1.5);
    while (n>0)
    {
     n--;
     printf("il reste %d seconde", n);
     sleep(1);
     printf("\x0d");

    }

    rendu = prix - 1;
    printf("\nRendu %feuro\n", rendu);
    printf("\nVeuillez prendre votre boisson!\n\n");
   }
   
   sleep(6);
   system("cls");
  }
 }


voila le code en entier ^^
Commenter la réponse de Leer0r