Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Exercice Java] Boucle do

24 août 2019 à 16:05:17

Bonjour, je dois écrire un programmer qui permet de convertir des degrés Celsius en Fahrenheit et inversement. Comment puis-je retourner au début de ma boucle une fois que le programme arrive à la dernière instruction ? Je voudrais inviter l'utilisateur à faire une nouvelle conversion. Mais il y a une erreur dans mon code car le programme affiche toujours "Voulez-vous faire une nouvelle conversion ? (O/N)" peu importe le caractère que je saisie.

Je suis désolé pour mon code, mais je ne sais pas comment le rendre plus lisible sur Openclassroom...

Est-ce qu'il faut obligatoirement respecter le code couleur (mot-clés, déclaration etc.)  ? car je voudrais mettre des couleurs plus sombre pour que ce soit mieux lisible.

Je vous remercie

package fr.willy.convertisseur;

import java.util.Scanner;

public class Mconvertisseur {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("Bonjour");
		System.out.println("Taper 1 pour convertir du Celsius en Fahrenheit ou taper 2 pour convertir du Fahrenheit en Celsius");
		char reset = ' ';
		int conversion;
		
		do 
		{
			Scanner sc = new Scanner(System.in);
			conversion = sc.nextInt();
			if (conversion == 1) 
			{
				System.out.println("Vous avez opté pour convertir du Celsius en Fahrenheit !");
				System.out.println("Combien de degrés Celsius voulez-vous convertir en Fahrenheit ?");
				int aConvertir = sc.nextInt();
				int formule = ((9/5)*aConvertir)+32;
				int résultat = formule;
				System.out.println("La conversion en Fahrenheit est de :" + résultat);				
			}
			else if (conversion == 2)
			{
				System.out.println("Vous avez opté pour convertir du Fahrenheit en Celsius !");
				System.out.println("Combien de degrés Fahrenheit voulez-vous convertir en Celsius ?");
				int aConvertir = sc.nextInt();
				int formule = ((aConvertir-32)*5)/9;
				int résultat = formule;
				System.out.println("La conversion en Celsius est de :" + résultat);	
			}
			else 
			{
				System.out.println("Veuillez recommencer");
			}
		do
		{
			System.out.println("Voulez-vous faire une nouvelle conversion ? (O/N)");
			sc.next().charAt(0);
		
		}while(reset != 'O' && reset != 'N');
		}while(conversion != 1 && conversion != 2);

	}

}

-
Edité par Zen_Zen 24 août 2019 à 18:28:35

  • Partager sur Facebook
  • Partager sur Twitter
24 août 2019 à 18:00:10

Bonjour,

Pour rendre ton code plus lisible sur le forum, tu peux utiliser le bouton </> 

Après en qui concerne l'erreur de boucle dans ton programme il faut mettre :

reset = sc.nextLine().charAt(0);

à la place de  

sc.next().charAt(0);


Ensuite il a quelques autres choses à modifier comme :

1-déplacer le texte "Taper 1" dans la boucle do

2- vider la ligne du scanner avec :

sc.nextLine();

3-  mettre while (reset == 'O'); à la place de while(conversion != 1 && conversion != 2);

Voilà au final tu auras un code comme ça :

package fr.willy.convertisseur;

import java.util.Scanner;

public class Mconvertisseur {

	public static void main(String[] args) {

// TODO Auto-generated method stub

		System.out.println("Bonjour");

		char reset = ' ';

		int conversion;

		do

		{
			System.out.println(
					"Taper 1 pour convertir du Celsius en Fahrenheit ou taper 2 pour convertir du Fahrenheit en Celsius :");

			Scanner sc = new Scanner(System.in);

			conversion = sc.nextInt();

			if (conversion == 1)

			{

				System.out.println("Vous avez opté pour convertir du Celsius en Fahrenheit !");

				System.out.println("Combien de degrés Celsius voulez-vous convertir en Fahrenheit ?");

				int aConvertir = sc.nextInt();

				int formule = ((9 / 5) * aConvertir) + 32;

				int résultat = formule;

				System.out.println("La conversion en Fahrenheit est de :" + résultat);

			}

			else if (conversion == 2)

			{

				System.out.println("Vous avez opté pour convertir du Fahrenheit en Celsius !");

				System.out.println("Combien de degrés Fahrenheit voulez-vous convertir en Celsius ?");

				int aConvertir = sc.nextInt();

				int formule = ((aConvertir - 32) * 5) / 9;

				int résultat = formule;

				System.out.println("La conversion en Celsius est de :" + résultat);

			}

			else

			{

				System.out.println("Veuillez recommencer");

			}

			do

			{

				System.out.println("Voulez-vous faire une nouvelle conversion ? (O/N)");

				// Pensez à vider la ligne lue
				sc.nextLine();
				reset = sc.nextLine().charAt(0);

			} while (reset != 'O' && reset != 'N');

		} while  (reset == 'O');

	}

}




  • Partager sur Facebook
  • Partager sur Twitter
24 août 2019 à 18:53:22

Merci pour votre réponse ! :)

J'ai suivi vos conseils et ça fonctionne très bien :) 

Mais... mon code n'est pas parfait et je cherche l'erreur..

C'est à dire que si je tape un autre chiffre que 1 ou 2, le programme exécute l'instruction  "System.out.println("Veuillez recommencer");" puis exécute ensuite l'instruction "System.out.println("Voulez-vous faire une nouvelle conversion ? (O/N)");"

Tout se passe bien ensuite.

plus précisément ce qui me gêne c'est qu'il ne repropose pas directement de choisir parmi les 2 choix possibles (Celsius ou Fahrenheit)

Voici ce qui s'affiche dans la console :

Bonjour
Taper 1 pour convertir du Celsius en Fahrenheit ou taper 2 pour convertir du Fahrenheit en Celsius
7
Veuillez recommencer
Voulez-vous faire une nouvelle conversion ? (O/N)
N
Bye

Et voici mon code : 

package fr.willy.convertisseur;

import java.util.Scanner;

public class Mconvertisseur {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("Bonjour");

		char reset = 'O';
		int conversion;
		
		do 
		{
			System.out.println("Taper 1 pour convertir du Celsius en Fahrenheit ou taper 2 pour convertir du Fahrenheit en Celsius");
			Scanner sc = new Scanner(System.in);
			conversion = sc.nextInt();
			if (conversion == 1) 
			{
				System.out.println("Vous avez opté pour convertir du Celsius en Fahrenheit !");
				System.out.println("Combien de degrés Celsius voulez-vous convertir en Fahrenheit ?");
				int aConvertir = sc.nextInt();
				int formule = ((9/5)*aConvertir)+32;
				int résultat = formule;
				System.out.println("La conversion en Fahrenheit est de :" + résultat);				
			}
			else if (conversion == 2)
			{
				System.out.println("Vous avez opté pour convertir du Fahrenheit en Celsius !");
				System.out.println("Combien de degrés Fahrenheit voulez-vous convertir en Celsius ?");
				int aConvertir = sc.nextInt();
				int formule = ((aConvertir-32)*5)/9;
				int résultat = formule;
				System.out.println("La conversion en Celsius est de :" + résultat);	
			}
			else 
			{
				System.out.println("Veuillez recommencer");
			}
		do
		{
			System.out.println("Voulez-vous faire une nouvelle conversion ? (O/N)");
			sc.nextLine();
			reset = sc.nextLine().charAt(0);
			
		
		}while(reset != 'O' && reset != 'N');
		}while(reset == 'O');
		System.out.println("Bye");
	}

}




-
Edité par Zen_Zen 24 août 2019 à 18:57:25

  • Partager sur Facebook
  • Partager sur Twitter
24 août 2019 à 20:06:00

Pour résoudre ce problème tu as simplement à faire une boucle do while au niveau de la première question avec le scanner. En gros, si le choix est différent de 1 ou 2 la boucle revient au début du menu. Je te laisse la faire car c'est le même principe que les autre boucles do while, tu devrais arriver à le faire.
  • Partager sur Facebook
  • Partager sur Twitter
24 août 2019 à 22:31:11

J'ai placé la boucle do while, mais ça me fait une boucle infini "Veuillez recommencer"...

Pour éviter la boucle infini, j'ai fait un scanner en dessous de l'instruction "System.out.println("Veuillez recommencer"); 

ça fonctionne, mais le programme passe directement à la boucle suivante... elle ne revient pas au début...

package fr.willy.convertisseur;

import java.util.Scanner;

public class Mconvertisseur {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("Bonjour");

		char reset = 'O';
		int conversion;
		
		do 
		{
			System.out.println("Taper 1 pour convertir du Celsius en Fahrenheit ou taper 2 pour convertir du Fahrenheit en Celsius");
			Scanner sc = new Scanner(System.in);
			conversion = sc.nextInt();
			do {
			if (conversion == 1) 
			{
				System.out.println("Vous avez opté pour convertir du Celsius en Fahrenheit !");
				System.out.println("Combien de degrés Celsius voulez-vous convertir en Fahrenheit ?");
				int aConvertir = sc.nextInt();
				int formule = ((9/5)*aConvertir)+32;
				int résultat = formule;
				System.out.println("La conversion en Fahrenheit est de :" + résultat);				
			}
			else if (conversion == 2)
			{
				System.out.println("Vous avez opté pour convertir du Fahrenheit en Celsius !");
				System.out.println("Combien de degrés Fahrenheit voulez-vous convertir en Celsius ?");
				int aConvertir = sc.nextInt();
				int formule = ((aConvertir-32)*5)/9;
				int résultat = formule;
				System.out.println("La conversion en Celsius est de :" + résultat);	
			}
			else
			{
				System.out.println("Veuillez recommencer");
				conversion = sc.nextInt();
			}
			}while(conversion != 1 && conversion != 2);
		do
		{
			System.out.println("Voulez-vous faire une nouvelle conversion ? (O/N)");
			sc.nextLine();
			reset = sc.nextLine().charAt(0);
			
		}while(reset != 'O' && reset != 'N');
		}while(reset == 'O');
		System.out.println("Bye");
	}

}



  • Partager sur Facebook
  • Partager sur Twitter
24 août 2019 à 23:06:43

C'est presque ça, il suffit déplacer le while vers le haut et le do aussi doit partir de la première ligne "taper 1". Après on déplace la variable scanner car pour qu'elle soit reconnue il faut qu'elle soit en dehors des boucles et ça fonctionne :

import java.util.Scanner;

public class Mconvertisseur {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Scanner sc = new Scanner(System.in);
		char reset = 'O';
		int conversion;

		System.out.println("Bonjour");
		do {
			do {
				System.out.println(
						"Taper 1 pour convertir du Celsius en Fahrenheit ou taper 2 pour convertir du Fahrenheit en Celsius :");

				conversion = sc.nextInt();

				if (conversion != 1 && conversion != 2)
					System.out.println("Mode inconnu, veuillez refaire votre choix.");

			} while (conversion != 1 && conversion != 2);

			if (conversion == 1) {
				System.out.println("Vous avez opté pour convertir du Celsius en Fahrenheit !");
				System.out.println("Combien de degrés Celsius voulez-vous convertir en Fahrenheit ?");
				int aConvertir = sc.nextInt();
				int formule = ((9 / 5) * aConvertir) + 32;
				int résultat = formule;
				System.out.println("La conversion en Fahrenheit est de :" + résultat);
			} else if (conversion == 2) {
				System.out.println("Vous avez opté pour convertir du Fahrenheit en Celsius !");
				System.out.println("Combien de degrés Fahrenheit voulez-vous convertir en Celsius ?");
				int aConvertir = sc.nextInt();
				int formule = ((aConvertir - 32) * 5) / 9;
				int résultat = formule;
				System.out.println("La conversion en Celsius est de :" + résultat);
			}

			else {
				System.out.println("Veuillez recommencer");
				conversion = sc.nextInt();
			}
			;
			do {
				System.out.println("Voulez-vous faire une nouvelle conversion ? (O/N)");
				sc.nextLine();
				reset = sc.nextLine().charAt(0);

			} while (reset != 'O' && reset != 'N');
		} while (reset == 'O');
		System.out.println("Bye");
	}

}



  • Partager sur Facebook
  • Partager sur Twitter
25 août 2019 à 11:15:37

Rebonjour,

j'ai fais les modifications.. ça me fait une boucle infini :/

Je vais essayer de résoudre ce problème..

Je vous donne quand même mon code :

package fr.willy.convertisseur;

import java.util.Scanner;

public class Mconvertisseur {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("Bonjour");

		char reset = 'O';
		int conversion;
		
		do 
		{
			System.out.println("Taper 1 pour convertir du Celsius en Fahrenheit ou taper 2 pour convertir du Fahrenheit en Celsius");
			Scanner sc = new Scanner(System.in);
			conversion = sc.nextInt();
			do {
				
				 if (conversion != 1 && conversion != 2)
	                    System.out.println("Mode inconnu, veuillez refaire votre choix.");
				 
			} while (conversion != 1 && conversion != 2);
				 
			if (conversion == 1) 
			{
				System.out.println("Vous avez opté pour convertir du Celsius en Fahrenheit !");
				System.out.println("Combien de degrés Celsius voulez-vous convertir en Fahrenheit ?");
				int aConvertir = sc.nextInt();
				int formule = ((9/5)*aConvertir)+32;
				int résultat = formule;
				System.out.println("La conversion en Fahrenheit est de :" + résultat);				
			}
			else if (conversion == 2)
			{
				System.out.println("Vous avez opté pour convertir du Fahrenheit en Celsius !");
				System.out.println("Combien de degrés Fahrenheit voulez-vous convertir en Celsius ?");
				int aConvertir = sc.nextInt();
				int formule = ((aConvertir-32)*5)/9;
				int résultat = formule;
				System.out.println("La conversion en Celsius est de :" + résultat);	
			}
			else
			{
				System.out.println("Veuillez recommencer");
				conversion = sc.nextInt();
			}
		do
		{
			System.out.println("Voulez-vous faire une nouvelle conversion ? (O/N)");
			sc.nextLine();
			reset = sc.nextLine().charAt(0);
			
		}while(reset != 'O' && reset != 'N');
		}while(reset == 'O');
		System.out.println("Bye");
	}

}



  • Partager sur Facebook
  • Partager sur Twitter
25 août 2019 à 15:51:11

Bonjour,

Regarde bien le code donné par Nemo404 : il te faut déplacer ton scanner en dehors de la boucle. (son code marche impeccable)

Scanner sc = new scanner(System.in);



Sinon pour info : ta formule pour transformer du Celsius en Fahrenheit est mal rédigée et donc donne de mauvaises réponses, essaye de la rectifier, si tu ne trouves pas je t'aiderais.

a plus tard, je débute en JAVA et donc c'est enrichissant de chercher les réponses aux problèmes posés par d'autres ;) 

  • Partager sur Facebook
  • Partager sur Twitter
26 août 2019 à 10:04:28

GeraudMonteils a écrit:

Regarde bien le code donné par Nemo404 : il te faut déplacer ton scanner en dehors de la boucle. (son code marche impeccable)

Non, le problème ne vient pas de là.
C'es vrai que la définition du scanner serait mieux en-dehors de la boucle parce qu'on utilise en principe toujours le même scanner, mais si on en redéfinit un à chaque fois ça marche aussi. C'est juste moins optimisé.

Le vrai problème vient d'ici :

System.out.println("Voulez-vous faire une nouvelle conversion ? (O/N)");
sc.nextLine();
reset = sc.nextLine().charAt(0);

Tu appelles deux fois nextLine(), donc tu lis deux lignes du scanner au lieu d'une. Et comme tu n'interprètes pas la première, la réponse à la question est purement et simplement ignorée.

  • Partager sur Facebook
  • Partager sur Twitter
26 août 2019 à 18:34:12

J'ai déplacé le Scanner en dehors de la boucle et j'ai aussi supprimé l'instruction "sc.nextLine();".

Mais le problème de la boucle infini persiste... :/ Quand je lance le programme et que je tape un chiffre différent de 1 ou 2, le programme ne me pas propose de faire une nouvelle saisie.. au niveau de mon else Voici mon code.

package fr.willy.convertisseur;

import java.util.Scanner;

public class Mconvertisseur {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("Bonjour");

		char reset = 'O';
		int conversion;
		Scanner sc = new Scanner(System.in);
		
		do 
		{
			System.out.println("Taper 1 pour convertir du Celsius en Fahrenheit ou taper 2 pour convertir du Fahrenheit en Celsius");
			conversion = sc.nextInt();
			do {
				
				 if (conversion != 1 && conversion != 2)
	                    System.out.println("Mode inconnu, veuillez refaire votre choix.");
				 
			} while (conversion != 1 && conversion != 2);
				 
			if (conversion == 1) 
			{
				System.out.println("Vous avez opté pour convertir du Celsius en Fahrenheit !");
				System.out.println("Combien de degrés Celsius voulez-vous convertir en Fahrenheit ?");
				int aConvertir = sc.nextInt();
				int formule = ((9/5)*aConvertir)+32;
				int résultat = formule;
				System.out.println("La conversion en Fahrenheit est de :" + résultat);				
			}
			else if (conversion == 2)
			{
				System.out.println("Vous avez opté pour convertir du Fahrenheit en Celsius !");
				System.out.println("Combien de degrés Fahrenheit voulez-vous convertir en Celsius ?");
				int aConvertir = sc.nextInt();
				int formule = ((aConvertir-32)*5)/9;
				int résultat = formule;
				System.out.println("La conversion en Celsius est de :" + résultat);	
			}
			else
			{
				System.out.println("Veuillez recommencer");
				conversion = sc.nextInt();
			}
			reset = ' ';
		do
		{
			System.out.println("Voulez-vous faire une nouvelle conversion ? (O/N)");
			reset = sc.next().charAt(0);
			
			
		}while(reset != 'O' && reset != 'N');
		}while(reset == 'O');
		System.out.println("Bye");
	}

}

Puis quand je tape 1 ou 2, je donne une valeur à convertir, le programme fait le calcul. Mais ensuite, ça me donne une erreur .. 

Bonjour
Taper 1 pour convertir du Celsius en Fahrenheit ou taper 2 pour convertir du Fahrenheit en Celsius
1
Vous avez opté pour convertir du Celsius en Fahrenheit !
Combien de degrés Celsius voulez-vous convertir en Fahrenheit ?
45
La conversion en Fahrenheit est de :77
Voulez-vous faire une nouvelle conversion ? (O/N)
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
	at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:47)
	at java.base/java.lang.String.charAt(String.java:702)
	at convertisseur/fr.willy.convertisseur.Mconvertisseur.main(Mconvertisseur.java:52)


J'ai trouvé la réponse pour le Scanner sur ce lien "https://openclassrooms.com/forum/sujet/probleme-de-type-exception-in-thread-quot-mainquot-java-l-57342", mais je ne comprend pas pourquoi quand j'utilise "reset = sc.next().charAt(0);" à la place de "reset = sc.nextLine().charAt(0);" cela fonctionne...


Donc pour contourner le problème, j'ai modifié la ligne 53 : reset = sc.nextLine().charAt(0);

J'ai enlevé le "Line" ce qui donne "reset = sc.next().charAt(0);

et maintenant, ça fonctionne... mais la boucle infini est toujours d'actualité :/

Vous avez une explication par rapport à l'erreur du Scanner et de la boucle infini svp ?

Bon.. J'ai supprimé la condition else et depuis le code fonctionne parfaitement... mais si vous avez un code plus optimisé et des explications pour la boucle infini et le Scanner, je suis preneur.

Je vous remercie de m'avoir aidé ! :)

-
Edité par Zen_Zen 26 août 2019 à 19:17:54

  • Partager sur Facebook
  • Partager sur Twitter
26 août 2019 à 19:29:15

Le problème de la boucle infinie vient de la deuxième boucle do while qui doit commencer plus tôt, comme ça :

do {//début de la première boucle do while
			do {//début de la 2ème boucle do while
				System.out.println(
						"Taper 1 pour convertir du Celsius en Fahrenheit ou taper 2 pour convertir du Fahrenheit en Celsius:");
				conversion = sc.nextInt();

				if (conversion != 1 && conversion != 2)
					System.out.println("Mode inconnu, veuillez refaire votre choix.");

			} while (conversion != 1 && conversion != 2);//fin de la 2ème boucle do while


Pour le bug il vient du sc.nextLine(); qu'il faut garder si tu as utilisé l'instruction nextInt() juste avant d'utiliser nextLine() donc tu dois vider la ligne du scanner. C'est un bug qui est expliqué ici : https://openclassrooms.com/fr/courses/26832-apprenez-a-programmer-en-java/20615-apprenez-a-lire-les-entrees-clavier#/id/r-2180495

 Après c'est normal que reset = sc.next().charAt(0);fontionne car tu n'utilises pas nextLine() et donc tu n'as pas de bug. Après on utilise souvent nextLine car ça permet de lire une ligne entière. 

  • Partager sur Facebook
  • Partager sur Twitter
27 août 2019 à 9:37:03

J'avoue que je n'avais jamais vu le problème, d'autant que je n'ai vu le Scanner que dans les cours d'OpenClassrooms... mais c'est intéressant.

Zen_Zen a écrit:

Bonjour
Taper 1 pour convertir du Celsius en Fahrenheit ou taper 2 pour convertir du Fahrenheit en Celsius
1
Vous avez opté pour convertir du Celsius en Fahrenheit !
Combien de degrés Celsius voulez-vous convertir en Fahrenheit ?
45
La conversion en Fahrenheit est de :77
Voulez-vous faire une nouvelle conversion ? (O/N)
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
    at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:47)
    at java.base/java.lang.String.charAt(String.java:702)
    at convertisseur/fr.willy.convertisseur.Mconvertisseur.main(Mconvertisseur.java:52)
Pour le dire autrement, dans cet exemple tu as tapé ceci (les '\n' étant les fins de lignes insérées par la touche Entrée) :
1\n
45\n
77\n
O\n

Côté code, tu as appelé successivement la méthode nextInt() à plusieurs reprises (lignes 18, 30 et 47 de ton précédent post).
Java a donc cherché à chaque fois les nombres qui étaient saisis en ignorant tous les autres caractères, même \n.
Une fois arrivé dans la boucle finale ligne 52, il a donc lu ceci depuis le début du programme :

1\n
45\n
77

...et il lui reste à lire ceci (la touche Entrée après le 77, et la réponse suivante qui est du texte) :

\n
O\n

donc quand tu appelles nextLine() à la ligne 53, il lit d'abord une ligne vide.

La solution est d'appeler systématiquement nextLine() après chaque nextInt(), pour purger le caractère \n en fin de ligne :

int reponse = sc.nextInt();
sc.nextLine();
  • Partager sur Facebook
  • Partager sur Twitter