Continuous Scanner input - java

I'm writing sort of main practice project, where I can just continually add classes that do completely different fun things. For example, I have a CoinFlipperCmd and a poker PotOddsCmd, and the code currently works fine, but I want to be able to repeatedly enter commands without having to rerun the program. Example console currently:
FLIP 10 // coinflips 10 times and notes the outcome
You flipped 5 heads and 5 tails
After this, the code will exit, but I want to be able to keep entering commands. Like so:
FLIP 5
You flipped 4 heads and 1 tails
FLIP 6
You flipped 3 heads and 3 tails
POTODDS 0.5 1
You have pot odds of 2:1
I'm using a scanner for input
import java.util.Scanner; // Import the Scanner class
public class Main {
public static void main(String[] args) {
InputScanner();
}
private static void InputScanner() {
Scanner myObj = new Scanner(System.in); // Create a Scanner object
System.out.println("Enter command");
String command = myObj.nextLine(); // Read user input
ParseAndDirect(command);
}
private static void ParseAndDirect(String command) {
String[] commandSplit = command.split(" ", 2);
String usercommand = commandSplit[0];
if (usercommand.equals("FLIP")){
CoinFlipperCmd.CoinFlipperCmd(commandSplit[1]);
} else if (usercommand.equals("POTODDS")){
PotOddsCmd.PotOddsCmd(commandSplit[1]);
} else System.out.println("Invalid Command");
}
}

You need to put the input part inside a loop e.g.
private static void InputScanner() {
Scanner myObj = new Scanner(System.in); // Create a Scanner object
String command;
do {
System.out.print("Enter command (q to quit): ");
command = myObj.nextLine(); // Read user input
if (!command.equalsIgnoreCase("q")) {
ParseAndDirect(command);
}
} while (!command.equalsIgnoreCase("q"));
}
Another way of using the loop can be as follows:
private static void InputScanner() {
Scanner myObj = new Scanner(System.in); // Create a Scanner object
String command;
while(true)
System.out.print("Enter command (q to quit): ");
command = myObj.nextLine(); // Read user input
if (command.equalsIgnoreCase("q")) {
break;
}
ParseAndDirect(command);
}
}
On a side note (because it won't have any impact on the execution of the program), you should always follow Java naming conventions e.g the method, ParseAndDirect should be named as parseAndDirect and InputScanner should be named as inputScanner.

Apart from allowing the user to repeatedly enter commands, I think you should also allow some way to quit the program (besides having to kill it via the operating system :-) In the below code, I have arbitrarily used the word quit as the way to exit the loop. Feel free to use a different string.
Scanner myObj = new Scanner(System.in);
String command = "";
while (!"quit".equalsIgnoreCase(command)) {
System.out.println("Enter command");
if (!"quit".equalsIgnoreCase(command)) {
ParseAndDirect(command);
}
}
By the way, according to java naming conventions the method name should be parseAndDirect, i.e. it should start with a lowercase letter.

Related

Can I input all the command at once?

I implemented a java program with some methods. Next I created a main class which will call the related method by entering a word.
for example:
Enter {A|B|C|D|E} to call method. A=method one B = method two...etc
A<--this is the user input
Enter Number:<--the first Scanner input of method A
123<--Input 1
Enter words:<-- the second Scanner input of method A
ABC<--Input 2
123ABC<--The output method A
Enter {A|B|C|D|E} to call method. A=method one B = method two...etc
B<--this is the user input
Enter Number 1:<--the first Scanner input of method B
100<--Input 1
Enter Number 2:<-- the second Scanner input of method B
50<--Input 2
150<--The output method B
Code of Method A {
String output;
private static Scanner keyboard = new Scanner(System.in);
System.out.println("Enter Number:");
String no = keyboard.nextLine();
System.out.println("Enter Words:");
String words = keyboard.nextLine();
//do something...
System.out.println(output);
}
Code of Main class{
private static Scanner keyboard = new Scanner(System.in);
public static void main(String[] args){
Main main = new Main();
main.run();
}
public void run() {
boolean running = true;
while (running) {
displayMenu();
String command = keyboard.nextLine();
String[] parts = command.split("^");
if ("A".equalsIgnoreCase(command)) {
//call method A
} else if ("B".equalsIgnoreCase(command)) {
//call method B
} else if....etc
System.out.println();
}
what I want is input
A123 , ABCB100,50 at once
then the system will print the output of method A (123ABC) and B (150) for me.
What I want is input A into "keyboard", input 123 into "no" and input ABC into "words" at once
How can I do it?
As long as your don't close your Scanner (or its underlying input stream), the yet-to-read tokens will remain accessible for later use : read two lines (or 4 tokens - the comma is one) and "B\n100,50" will remain.
If you're asking how to provide this kind of input, it depends on your invokation method. If executed from bash, I'd use the following :
echo """A
123 , ABC
B
100,50""" | java ...
If you're asking how to dynamically invoke a method from its name, check the reflection API. Oracle's tutorial is a good resource in my opinion, here's a link to its section on retrieving and invoking methods.
There are 2 ways to do that.
First:
Instead of giving input directly in the console, first write all the data input somewhere and just copy it and paste it in the console.
Second:
You can use hasNexLine() and send EOF through keyboard by pressing ctrl+d.
Code:
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
StringBuilder sb = new StringBuilder();
while(s.hasNextLine())
{
sb.append(s.nextLine());
}
System.out.println(sb.toString());
}
Provide all your input and press ctrl+d to stop taking input.

Program goes in an infinite loop

This program goes in an infinite loop in while cycle. Please, can someone tell me why?
import java.util.Scanner;
public class program {
public static void main(String[] pars) {
System.out.println("Insert something.");
Scanner read = new Scanner(System.in);
String s = "";
while(read.hasNext()) {
System.out.println(read.next());
}
System.out.println("End of program");
}
}
Read the Javadoc of Scanner#hasNext():
Returns true if this scanner has another token in its input. This method may block while waiting for input to scan. The scanner does not advance past any input.
Hence the while loop will always be executed in your case, each time waiting for input from the user. Since the Scanner is linked to System.in, the input stream will always block until the user inputs a string and hasNext() will always return true, unless the user signals the end of file (e.g. through the Ctrl+z combination on Windows). Scanner#hasNext() is more convenient when reading from files where the input size is known and the end of the file marks the end of the stream.
One way to end the loop here is to add a condition on the input:
while (read.hasNext()) {
s = read.next();
if(s.equals("quit")) {
break;
}
System.out.println(s);
}
P.S.: It is more conventional to name classes starting with an uppercase letter.
The problem is this line:
while(read.hasNext()) {
If you use System.in as a stream provided by the user, it will - if no such input is available - as #manouti says, block and wait for input. But even if you provide input, it will keep waiting. The system has no means to detect whether the user wants to provide additional input in the future.
It will only stop, if the Stream ends. This can be under two conditions:
The end of the file (in case of I/O redirection like java -jar program.jar < input.dat; or
The user marks the end of a stream, in most shells with Ctrl+D. This marks the end-of-stream.
An alternative is to provide some kind of stop directive. Something like "END". Thus:
while(read.hasNext()) {
String nx = read.next();
if(nx.equals("END")) {
break;
}
System.out.println(nx);
}
Just remove while loop
public static void main(String[] pars) {
System.out.println("Insert something.");
Scanner read = new Scanner(System.in);
String s = "";
System.out.println(read.next());
System.out.println("End of program");
}
Or if u want display certain no.of string then mention condition properly.
public static void main(String[] pars) {
System.out.println("Insert something.");
Scanner read = new Scanner(System.in);
String s = "";
int i=0;
while(i<5) {
System.out.println(read.next());
i++;
}
System.out.println("End of program");
}

How to make a ONE static scanner global variable without closing scan constantly and use it within methods and the main method?

I want to create a static scanner but i will like to put the try catch block around it so it can automatically close avoiding resources
leaks and or this exception:
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1585)
at softwareEngineer.UserApp1.main(UserApp1.java:82)
Essentially I only want to create one static scanner declaration and use it throughout the main program and includes the static methods, at this point my code will require to create separate scanner for each method and you are force "scan.close()". the code below will recieve a exception handling error due to multiple scanner that was open and did not closein the program.
I updated the code now i get null pointer exception
import java.util.Scanner;
public class UserApp1 {
static User currentCustomer = null; //single object
static Scanner scan;
//-------------------------------------------------------
// Create a list, then repeatedly print the menu and do what the
// user asks until they quit
//-------------------------------------------------------
public static void main(String[] args) {
scan = new Scanner(System.in);)//scanner to avoid resource leak
printMenu(); //print menu system from another function
String choice = scan.nextLine(); //reads an input
final String EXIT_now = "0";
final String BACK = "back";
while (!(choice.equalsIgnoreCase(EXIT_now))){
switch(choice) {
case 1: break;
case 2:
currentCustomer = loginInput();<---- errors happens here
if(currentCustomer != null){
System.out.println("You have successfully login");
}
break;
default:
System.out.println("Sorry, invalid choice");
break;
} //ends switch
printMenu(); //print menu system from another function
choice = scan.nextLine(); //reads an input
}//ends while
System.out.println("\t\t GoodBye!\n Thank you for trying our program.");
System.exit(0);
}//ends main
//----------------------------
// Print the user's choices
//----------------------------
public static void printMenu() {
System.out.println("\t\t The User Login System ");
System.out.println("\t\t ======================");
System.out.println("The Menu Options:");
System.out.println("1: Register an Account");
System.out.println("2: Login to your Account");
System.out.println("3: Reset Password");
System.out.println("0: Quit/Exit ");
System.out.println("Please enter your selection > ");
} //ends printMenu
public static User loginInput(){
System.out.print( "\nFollow the Prompts to Log-In to your Account \n ");
System.out.print( "\nPlease enter your userid : \n ");
String userid = scan.nextLine();// <---- errors happens here
System.out.print( "\nPlease enter your password: \n ");
String pass = scan.nextLine();
currentCustomer = AccountList.loginUser(userid, pass);
if (currentCustomer != null)
{
return currentCustomer;
}
return null;
}//ends loginInput
}//ends class*
You're using a try-with-resources, which will automatically close it when you finish the try block. Try setting it to a variable like so:
public class MyClass {
private static Scanner scan;
public static void main(String[] args) {
scan = new Scanner(System.in);
}
}
Avoid making multiple scanners with the System.in input as well, as they will consume the stream and then you have an entirely different problem.
Avoid using a static global Scanner at all, by passing the Scanner instance you want to work with to the relevant methods. Consider this simplified example:
public static void main(String[] args) {
try(Scanner in = new Scanner(System.in)) {
String choice = in.nextLine().trim();
if(choice.equals("1")) {
doOp1(in);
} else if(choice.equals("2")) {
doOp2(in);
} else {
System.err.println("Invalid choice. Goodbye.");
}
}
}
// Method takes an open, functioning Scanner as an argument, therefore
// it doesn't need to close it, or worry about where it came from, it
// simply uses it, does what it needs to do, and returns, trusting
// the caller to properly close the Scanner, since it opened it.
private void doOp1(Scanner in) {
System.out.print("What is your name? ");
String name = in.nextLine().trim();
System.out.print("What is your favorite color? ");
String color = in.nextLine().trim();
}
private void doOpt2(Scanner in) {
...
}
You want to compartmentalize your resources to ensure they are limited in scope and easy to close. Putting them in global state of any kind makes that very difficult. Instead, separate the opening and closing of the resource from the code using it. This sort of compartmentalization makes for much more maintainable, readable, and testable code.
For instance, by passing an already open Scanner to your core business logic functions, you can mock a real user's behavior and create a test to ensure your code remains stable, by constructing a Scanner that reads from a hard coded String, and passing that into your method, without needing to run the whole class and type in the behavior your testing manually again and again.

How do I set the statement if to read letters instead of numbers?

"if" statement only allows to put numbers in it.
Is there a way to make it read letters?
I'm only in my fifth lesson of Java (I study in a uni and the teacher is very slow but I want to learn things fast)
for example.
import java.util.Scanner;
public class Java {
public static void main (String [] args) {
Scanner scan = new Scanner(System.in);
int answer1;
System.out.println("Do you like Java?");
answer1 = scan.nextInt();
if (answer1 == yes)
System.out.println("Cool ~");
else
System.out.println("Ehh...");
}
}
I want to put "yes" instead of the number 5.
So if the user types "yes" it will print "correct".
P.S. I didn't find a clear answer to that in the search engine.
It's not a duplicated thread as I'm trying to find a clear answer to that.
I need a detailed explanation about it.
I'm still a beginner, using those "high tech java words" won't help me.
You need to modify your program so that your scanner to reads a String instead of an int. You can do that as:
import java.util.Scanner;
public class Java {
public static void main (String [] args) {
Scanner scan = new Scanner(System.in);
String answer1;
System.out.println("Do you like Java?");
answer1 = scan.next();
if (answer1.equals("yes"))
System.out.println("Cool ~");
else
System.out.println("Ehh...");
}
}
I used next() for this since we only want one word (token), but be aware that there are other options for reading Strings.
Notice also that I've changed the test in the condition because it's now a String. See this answer for more on comparing Strings.
You need to modify your program so that your scanner to reads a String instead of an int. You can do that as:
import java.util.Scanner; public class Java {
public static void main (String [] args) {
Scanner scan = new Scanner(System.in);
String answer1;
System.out.println("Do you like Java?");
answer1 = scan.next();
if (answer1.equals("yes"))
System.out.println("Cool ~");
else
System.out.println("Ehh...");
} }
I used next() for this since we only want one word (token), but be aware that there are other options for reading Strings.
Notice also that I've changed the test in the condition because it's
now a String. See this answer for more on comparing Strings.
Ok, what if you want the program to read both words and numbers:
Here's my program (more in depth, when you see the full thing), but this is one of 5 parts (that look a like) where I'm having the program...
public static void Gdr1() {
try {
System.out.print("[Code: Gdr1] Grade 1: %");
Scanner gdr1 = new Scanner(System.in);
Z = gdr1.next();
Z = Double.toString(Grd1);
Grd1 = Double.parseDouble(Z);
if ((Grd1<100)&&(Grd1>=5)) {
Gdr2();
} else if ((Grd1>=100)&&(Grd1<125)) {
System.out.println(" System> Great Job "+Stu+"!");
Gdr2();
} else if (Grd1<5) {
System.out.println("I'm sorry, the lowest grade I am allowed to compute is 5...");
Gdr1();
} else if (Z.equalsIgnoreCase("restart")) {
restart01();
} else {
System.out.println("("+Z+") cannot be resolved in my system...");
Gdr1();
}
} catch (Exception e) {}
}
Now everything works in the program, besides for when the End-User's input = "restart", I know some of the code in the program seems complicated, but it does work (most of it), can anyone help me try to figure this out, its for my portfolio at my school due latest by 1/25/2017 # 11:59 pm.
The things like Z (constant String), ""+Stu+"" (variable input), and [Code: Gdr1] are there for a purpose...

Java Loop/User Input from Scanner

Making just a simple basketball program where I ask for the home team name, how many games are in the season, and then in a loop ask for the next team game. Basically when I start the do-while loop, it works great, unless the user types in for example, "Ohio State." The out put will then go from "6 games remaining" to "4 games remaining" for example. Usually it will just ask opponent?, then decrement by one game.
How can I fix so that a 2 word basketball team name doesn't decrement twice?
import java.util.Scanner;
public class Basketball2 {
public static void main(String[] args) throws java.io.IOException {
Scanner scanInput = new Scanner(System.in);
String sHomeTeam;
String sAwayTeam;
int iNumGames;
int iGamesLeft = 0;
System.out.println("Enter home team's name: ");
sHomeTeam = scanInput.nextLine();
System.out.println(sHomeTeam);
System.out.println("How many games are in the home team's basketball season?");
iNumGames = scanInput.nextInt();
System.out.println(iNumGames);
//start looping
do {
System.out.println("Enter opponent team's name: ");
sAwayTeam = scanInput.next();
System.out.println(sAwayTeam);
iGamesLeft = --iNumGames;
System.out.println("There are " + iGamesLeft + " games left in the basketball season");
}//end do
while(iGamesLeft > 0);
Replace: sAwayTeam = scanInput.next(); with sAwayTeam = scanInput.nextLine(); The reason it loops twice is because scanInput.next(); only returns one token (e.g. word) at a time. When you enter two words it doesn't need receive more input from the user before continuing a second time because it already has another word to return. Hence the double loop.
You also need to take care of the line of code that calls nextInt(). This works like the next() method, but, instead of a token (word), it scans in just one character as an int. Try this: after iNumGames = scanInput.nextInt(); put scanInput.nextLine(); This should clear scanInput of anything that is making it skip. Note: because of the way that your code is written, this will only read one character. If you need to read more than one character you should use nextLine() and assign its value to an integer.
Whatever is said in the answer given by Donny Schrimsher is correct. All that you have to do now is after getting the number of games in the home team's basketball season i.e.
System.out.println("How many games are in the home team's basketball season?");
iNumGames = scanInput.nextInt();
You have to add
scanInput.nextLine();
This is because after entering the number of games you press enter key (end of line) and nextInt() method takes the number of games and not the end-of-line. This end-of-line is consumed by the nextLine() method which Donny Schrimsher mentioned in the do-while loop. SO to avoid this you add an extra nextLine() method.
Thus it has to be
System.out.println("How many games are in the home team's basketball season?");
iNumGames = scanInput.nextInt();
scanInput.nextLine();
System.out.println(iNumGames);
plus the changes mentioned by Donny Schrimsher.
Thanks
try below code with all exit functionality also.
import java.util.Scanner;
public class Basketball2 {
public static void main(String[] args) throws java.io.IOException {
Scanner scanInput = new Scanner(System.in);
String sHomeTeam;
String sAwayTeam;
int iNumGames;
int iGamesLeft = 0;
System.out.println("Enter home team's name: ");
sHomeTeam = scanInput.nextLine();
System.out.println(sHomeTeam);
System.out
.println("How many games are in the home team's basketball season?");
iNumGames = scanInput.nextInt();
System.out.println(iNumGames);
// start looping
do {
System.out.println("Enter opponent team's name: ");
scanInput = new Scanner(System.in);
sAwayTeam = scanInput.nextLine();
if(!"".equals(sAwayTeam.trim()) && !"exit".equals(sAwayTeam.trim()))
{
System.out.println(sAwayTeam);
iGamesLeft = --iNumGames;
System.out.println("There are " + iGamesLeft+ " games left in the basketball season");
}
}// end do
while (iGamesLeft > 0 && !"exit".equalsIgnoreCase(sAwayTeam));
}
}
Subject: 'Java Loops' with Scanner
The simple Java program I wrote is working perfectly, you can try for yourself...and you also can convert this program easily into 'while loop', 'do - while loop' and 'for - each loop'.
Rafiq,
VA, USA,
Dated: 04/17/2015
//Examples: 'for loop' with Scanner
package com.java_basics;
import java.util.Scanner;
public class ForLoop_Examples_With_Scanner
{
public static void main(String[] args)
{
//Creating instance of Scanner to allows a user's input to read from System.in
Scanner mySC = new Scanner(System.in);
System.out.println("Please, enter the value of 'int i' between '0 and 2' : ");
int i = mySC.nextInt();
System.out.println("Please, enter the value of 'exitPoint' between '10 and 1000' :");
int exitPoint = mySC.nextInt();
System.out.println("Please, enter the value of 'increment' between '1 and 2' :");
int increment = mySC.nextInt();
mySC.close();//Releasing memory to the OS (Operating System) for reuse
System.out.println("Output:\n" + "======");
for(;i<exitPoint ; i=i+increment)//i++==>i=i+1==>i=i+increment
{
System.out.println(i);
}
}
}

Categories

Resources