Java passing scanner into method - java

So I'm going through a bunch of basic programming ideas to help me get the hang of Java and I created a program that will print PI up to the 10th decimal place (and I can add more if I want).
However, I decided to go an extra step and create an option to keep running the program over and over until the user tells it to stop. I created a method to return either true (run again) or false (exit program). Originally I created a scanner in the method to take user input, and the program runs fine that way, but it tells me I have a resource leak because I didn't close the scanner in the method.
I have just passed the input scanner from main to the method as a parameter, but when I run the program it doesn't accept user input and will print out "Sorry, there was an error" (the else{} option in the if-else statement in my method). Now, I can go back and create a seperate scanner but my OCD doesn't want Eclipse telling me there is a resource leak (I think input.close() closes both scanners, but I am not sure).
Here is my code, I apologize to any Java enthusiasts who become smitten and offended at any bad practices I am unaware of, I am learning.
import java.util.Scanner;
import java.text.DecimalFormat;
public class PiDecimalFormat {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
DecimalFormat format = new DecimalFormat("#");
int decPlace = 0;
boolean runProgram = true;
System.out.println("This program will print out PI to the decimal place of your choosing.");
while (runProgram == true) {
System.out.print("\nEnter the number of decimal places (up to 10) that \nyou would like to print PI to: ");
decPlace = input.nextInt();
switch (decPlace) {
case 0:
format = new DecimalFormat("#");
break;
case 1:
format = new DecimalFormat("#.#");
break;
case 2:
format = new DecimalFormat("#.##");
break;
case 3:
format = new DecimalFormat("#.###");
break;
case 4:
format = new DecimalFormat("#.####");
break;
case 5:
format = new DecimalFormat("#.#####");
break;
case 6:
format = new DecimalFormat("#.######");
break;
case 7:
format = new DecimalFormat("#.#######");
break;
case 8:
format = new DecimalFormat("#.########");
break;
case 9:
format = new DecimalFormat("#.#########");
break;
case 10:
format = new DecimalFormat("#.##########");
break;
}
System.out.println("\nThe value of PI to " + decPlace + " decimal places is " + format.format(Math.PI) + ".");
runProgram = AskRunAgain(input);
}
input.close();
}
static boolean AskRunAgain(Scanner askUser) {
String userChoice;
System.out.print("\nWould you like to run the program again? [y/n]: ");
userChoice = askUser.nextLine();
if ((userChoice.equals("y")) || (userChoice.equals("Y")) || (userChoice.equals("yes")) ||
(userChoice.equals("Yes")) || (userChoice.equals("YES"))) {
return true;
}
else if ((userChoice.equals("n")) || (userChoice.equals("N")) || (userChoice.equals("no")) ||
(userChoice.equals("No")) || (userChoice.equals("NO"))) {
System.out.println("\nExitting the program. have a good day!");
return false;
}
else {
System.out.println("Sorry, there was an error.");
return false;
}
}
}
If anyone could tell me why it is doing this, I would appreciate it. I'm new to Java (decent with C/C++/C# and Python). I didn't see other questions about this specific problem, and it's not a big deal if I just create another scanner in the method.

I notice that you're doing this call:
decPlace = input.nextInt();
The return character isn't consumed, so it is still on the buffer as far as the Scanner is concerned.
This means, for an input of 2\n, it will read the 2 as the next integer, but read an empty string for the call to nextLine().
To get past this, finish consuming the line by using input.nextLine() after you read the next integer.
decPlace = input.nextInt();
input.nextLine();

Just change and it will work.
askUser.nextLine();
TO
askUser.next();
static boolean AskRunAgain(Scanner askUser) {
String userChoice;
System.out.print("\nWould you like to run the program again? [y/n]: ");
userChoice = askUser.next();

Related

java currency calculator pausing swtich to give output back to user

first question:
There is a do while loop, within the do section there is a switch. After selection case 1, some calculations are done, two options can result as shown in the If statement. My problem is code runs until the break; then just goes straight back to the menu loop. My question: how do i get the program to print the output for the user, then continue the menu loop?
Second question:
In case 1 there are two resulting options, the first being a failed response. from here, how do i get the program to loop back to the start of case 1 to ask for user input again? Even back to the main menu would be fine.
public static void showMenu() {
System.out.print('\u000c');
System.out.println("1 - Compute Change \n");
System.out.println("2 - Estimate Feast \n");
System.out.println("3 - \n");
System.out.println("4 - \n");
System.out.println("5 - I'm broke, get me out of here\n");
System.out.println("Select Option:\n");
}
public StackPost() {
System.out.println("Welcome to the Bank of Winterfell");
Scanner in = new Scanner(System.in);
do {
showMenu();
selection = in.nextInt();
switch (selection) {
case 1:
// get input, compute then decision:
if (something<somethingElse) {
// false response -
} else {
// correct response - system prints out some stuff back to user, back to main
// menu loop
}
break;
case 2:
break;
case 5:
System.out.println("\nEnding Now\n");
System.exit(0);
break;
default:
System.out.println("Instruction is invalid");
}
} while (selection != 5);
}
You could print "Press enter to continue" (or whatever you want to give notice of before locking the program), and add a call to Scanner#nextLine() before your break. This will lock the progression 'till user presses enter.
case 2:
// Some code here...
// Done, now show result and tell user to press any key to continue
System.out.println("Some fancy result from case handle code");
System.out.println("Press enter to continue...");
in.nextLine();
break;
You could add a while-loop that won't let the code continue 'till whatever input is expected in the first case is acceptable.
case 1:
System.out.println("Some handle that tells user to input something, and what is acceptable");
String input = null;
while(!(input = in.nextLine()).equals("something")) {
System.out.println("Wrong input, try again...");
}
// Input is acceptable, now do something with it...
System.out.println(input);
System.out.println("Press enter to continue...");
in.nextLine();
break;
Be aware, in your code, you call Scanner#nextInt(), and #nextInt doesn't consume the \n from pressing enter, and will thus be transferred into the switch case's usage of #nextLine(). You could avoid this with selection = Integer.parseInt(in.nextLine()).
You can use achieve it by:
For First question: Using return statement in case of correct response.
For Second question: Using while loop in case 1
After implementaing the proposed solution the StackPost() method will look like following. You can see the complete working code here:
public static void StackPost()
{
System.out.println("Welcome to the Bank of Winterfell");
try(Scanner in = new Scanner(System.in))
{
int selection;
do
{
showMenu();
selection = in.nextInt();
switch (selection)
{
case 1:
// get input, compute then decision:
while(true)
{
int something = in.nextInt();
int somethingElse = in.nextInt();
if (!(something<somethingElse)) {
// correct response - system prints out some stuff back to user, back to main
System.out.println("Print here the result");
// menu loop
return;
}
// false response - continue for next iteration in while-loop
}
//No need of 'break;' here
case 2:
break;
case 5:
System.out.println("\nEnding Now\n");
System.exit(0);
default:
System.out.println("Instruction is invalid");
}
} while (selection != 5);
}
}
Note: It is best practice to use try-with-resources while handling system resources which implements AutoCloseable interface.

How do I stack multiple Switches?

I'm currently testing running 2 or more switches, however I'm having issues with how they prioritise themselves. For example -
switch (Scanner Input)
{
case 1:
System.out.print("Example");
break;
case 2:
get.example();
break;
}
switch (Scanner Input2)
{
case 1:
System.out.print("Example");
break;
case 2:
get.example();
break;
}
If I was to run this, it would ask for both of my inputs and THEN does prints out/runs method. Instead of switch 1 > runs outcome > switch 2 > runs outcome. Also if there is a fix, is it possible to do it in a loop?
Hopefully this makes some kind of sense, I'm still new so my terminology is off. Thanks massively in advance!
you can do it by moving your switch logic to another method and then invoke it if it is meant to do the same, so you don't write it twice, here a piece of code that can help you and that's how I think you want to do this, I added some messages to the user there.
I removed the breaks in the cases because I'm using return, so it would be unreachable code.
import java.util.Scanner;
public class Pregunta {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Press 0 to exit.");
int input = scanner.nextInt();
while ( input != 0 )
{
System.out.println( switchUsersInput(input));
System.out.println("Press 0 to exit.");
input = scanner.nextInt();
}
System.out.println("Finish.");
}
public static String switchUsersInput( int input )
{
switch (input)
{
case 1:
return "Example";
case 2:
return "Example 2 I didn't get your get.example();";
default:
return "Chose something :)";
}
}
}

Methods, loops and randoms, oh my

I have an assignment at school to create a program with at least three separate methods that will act like a 'Magic Eight Ball". I have already created the method with 10 'responses' set to a 'switch' statement, based on a separate method that generates a random number between 0 and 9. What I need is a 'for', 'while', or 'do while' loop method that is supposed to continue asking questions until the word 'exit' is entered as a question. then I need a way to tie all of these methods together so they work right. I use a program called BlueJ (as instructed by the prof)
What I have so far is:
import java.util.*;
public class MagicEightBall
{
//Input method
public static void main(String[] args)
{
startAsking();
}
//Loop method
public static void startAsking()
{
do
{
Scanner input = new Scanner(System.in);
System.out.print("Enter Question: ");
System.out.println("Entering 'exit' ends program ");
if(input.nextLine().equalsIgnoreCase("exit"))
break;
System.out.println(getResponse());
}
while(true);
//input.close();
}
//Output method
public static String getResponse()
{
int numberOfResponses = 10;
int response = (int)(Math.random() * numberOfResponses);
String responseString;
switch (response)
{
case 1: System.out.println("Of course! H-A-L said so");
case 2: System.out.println("Yes, my young Padawan!");
case 3: System.out.println("V-ger has informed me that your answer is 'Yes'");
case 4: System.out.println("Mr. Spock says 'Not a chance, Captain'");
case 5: System.out.println("Only when Pi = apple would that be a 'Yes'");
case 6: System.out.println("There is no try, only do, or do not");
case 7: System.out.println("You know 'Big Brother' heard you ask that question?");
case 8: System.out.println("SyStEm MaLfUnCtIoN! pLeAsE tRy l8r");
case 9: System.out.println("No. That would cause a food fight");
default: System.out.println("I'm sorry, it's time for my oil bath");
}
return responseString;
}
}
Any help as to how to complete this would be greatly appreciated.
I build your code , then run it ;
reading about what are u asking its seems do everything (but not 100% correct) , in this steps:
1 ask u a question
2 answer u random
3 if asked "exit" he stop the program
can u explain me better what miss in your program that you need ? not doing at the moment?
for now i just can say you use a variable for append the question , than use the variable for go put from the loop also there is something not needed in the getresponse method
import java.util.*;
public class NewClass
{
//Input method
public static void main(String[] args)
{
startAsking();
}
//Loop method
public static void startAsking()
{
do
{
Scanner input = new Scanner(System.in);
System.out.print("Enter Question: ");
System.out.println("Entering 'exit' ends program ");
if(input.nextLine().equalsIgnoreCase("exit"))
break;
getResponse();
}
while(true);
//input.close();
}
//Output method
public static void getResponse()
{
int numberOfResponses = 10;
int response = (int)(Math.random() * numberOfResponses);
System.out.println(response);
switch (response)
{
case 1: System.out.println("Of course! H-A-L said so");break;
case 2: System.out.println("Yes, my young Padawan!");break;
case 3: System.out.println("V-ger has informed me that your answer is 'Yes'");break;
case 4: System.out.println("Mr. Spock says 'Not a chance, Captain'");break;
case 5: System.out.println("Only when Pi = apple would that be a 'Yes'");break;
case 6: System.out.println("There is no try, only do, or do not");break;
case 7: System.out.println("You know 'Big Brother' heard you ask that question?");break;
case 8: System.out.println("SyStEm MaLfUnCtIoN! pLeAsE tRy l8r");break;
case 9: System.out.println("No. That would cause a food fight");break;
default: System.out.println("I'm sorry, it's time for my oil bath");
}
}
}
dont care about some output i add for control the loop

Magic 8-ball program

I have an assignment for my Java class to program a Magic 8-ball. It is supposed to generate a random number for the response, contain a "while(true)" statement, and a switch statement for the replies. This is what I have so far. I can't seem to figure out how to work the "while(true)" statement in without it repeating infinitely.
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
String question;
int retry;
int q1;
System.out.print("What is your question for the Magic 8-bit 8-ball? ");
question = input.next();
System.out.print(process());
/*This is where I am having the problem. How do I work a "while(true)" in
* to where this won't infinitely repeat?
*/
}
public static int process() {
Random rand1 = new Random();
int random = rand1.nextInt(9);
int ans = random;
switch (ans) {
default: System.out.println("Does not compute!! Error! Error!");break;
case 1: System.out.println("The answer is.............. 42");break;
case 2: System.out.println("To get to the other side!!!");break;
case 3: System.out.println("Out of memory! Try again!");break;
case 4: System.out.println("Who do you think I am, IBM's Watson?");break;
case 5: System.out.println("Danger Will Robinson!! Danger!!");break;
case 6: System.out.println("What do you think?");break;
case 7: System.out.println("Fatal error.....nahhh just kidding");break;
case 8: System.out.println("Well, this is fun....NOT!");break;
case 9: System.out.println("Um...... 1,000,000,000,000,000,000,000?");break;
}
return ans;
}
}
Hum, the point of a while (true) loop is to be infinite, unless you add a break statement in it.
while (true) {
doStuff();
// if someCondition is true, this will exit the loop
if (someCondition)
break;
}
Note that this is equivalent to
do {
doStuff();
} while (!someCondition);
or
boolean someCondition = false;
while (!someCondition) {
doStuff();
}
It is usually preferrable to not have an infinite loop (while (true) for example) and have an explicit condition instead. Some exceptions exist, for example if the condition is complicated to express or if you want to break the loop at a particular position of the loop and not at the beginning or at the end :
while (true) {
doStuff();
if (someCondition)
break;
doSomeOtherStuff();
}
One of the many possible ways:
Create a a char and assign it to 'Y' (i.e. char continueLoop = 'Y').
Use this to control the while statement (i.e. while(char == 'Y') ).
Ask the user for input and process the input (i.e. System.out.println("Continue? Y/N") and then use Scanner to read the input and assign it to continueLoop.
You can create something similar using booleans.

Repeating to the main menu upon a specific user input

I am trying to create a simple program in java where the user can input some lines and then save it and then load the data from the saved file.
Currently, i have the basic outline of the program, but am stuck on the first stage where the user enters his data, then wishes to return to the main menu for another selection.
Code:
import java.io.*;
import java.util.*;
public class Datafile{
private static Scanner input = new Scanner(System.in);
public static void main(String[] args) throws IOException {
BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\Kence\\workspace\\Java 8 - Beyond the Basics - Working Files\\Practice Programs\\src\\Practice Data Edited",true));
String data = null;
String dataEntered = null;
int menuChoice = printMenu();
switch(menuChoice){
case 1:
System.out.println("Please enter a line of data");
dataEntered = input.nextLine();
if(Integer.parseInt(dataEntered) == 0){
System.out.println("OK");
//printMenu(); <--- Qn 1. Where i am stuck
return;
}else{
System.out.println(dataEntered);
}
//Why this does not recognize "quit" when entered
/*if(dataEntered == "quit"){ <--- Qn2. Where i am stuck
System.out.println("OK");
}else{
System.out.println("Error");
}*/
data += dataEntered;
System.out.println("Data entered.Please enter the next line of data or press quit to exit back to the main menu.");
break;
case 2:
System.out.println("2 Entered");
break;
case 3:
System.out.println("3 Entered");
break;
case 4:
System.out.println("4 Entered");
break;
}
input.close();
}
public static void printStars(){
for(int i = 0; i<66 ; i++){
System.out.print("*");
}
System.out.println();
}
public static int printMenu(){
printStars();
System.out.println("System Started");
printStars();
System.out.println("Enter 1 to input a new line of data");
System.out.println("Enter 2 to list all data");
System.out.println("Enter 3 to save existing data");
System.out.println("Enter 4 to load data");
printStars();
return Integer.parseInt(input.nextLine());
}
}
QN 1
In the code example above, when the user enters 0, the i can run printMenu(), but am unable to take any further action after that. I would like to be able to select the options 2,3 or 4 after the user enters 0.
Edit: printMenu works fine on the initial start-up, it's after i enter 1,input data, then press 0, that the new printMenu() does not work as i'm not actually testing the input with a switch statement. I can't figure out a way to run printMenu() again at this point without nesting another switch statement, and another switch statement after that and so on..
Qn2.
When i enter quit, the program does not output "OK", but outputs ERROR instead. I don't understand why this is happening as i am comparing the input (which is a string) with the string "quit", yet somehow the program does not recognise both strings as equals?
I would appreciate any clarifications and advice.
Thanks!
Qn1: Here's another way to retrieve the input, hopefully it will solve the problem:
public static int printMenu(){
...
intInput = input.nextInt();
input.nextLine();
return intInput;
}
Qn2: The == comparator is not used for strings. Try this instead:
if(dataEntered.equalsIgnoreCase("quit")) {
...
}

Categories

Resources