User prompt is one line off for some reason? - java

I'm asking for user input, but I want it to follow the enter: prompt and be on the same line.
My code produces this as a result input from 'ok'
ok
enter: ok
ok
I would like the user input to start after enter: - hoping for this as a result...
enter: ok
ok
Here's my code:
private static Scanner u = new Scanner(System.in);
try{
while(u.hasNext() && !u.equals("exit")) {
System.out.printf("enter: ");
usrInput = u.next();
System.out.printf(usrInput + "\n");
System.out.println(findClosestMatch(usrInput.toLowerCase()));
}
} catch(NullPointerException e) {
System.out.println("Error - NullPointerException");
}

u.hasNext() is blocking on input before the prompt. It's unnecessary, since calling u.next() afterwards will block anyway. And you're comparing the actual Scanner object to "exit", which will never be true. Try this:
while (true) {
System.out.print("enter: ");
if (!u.hasNext() || (usrInput = u.next()).equals("exit")) {
break;
}
System.out.println(usrInput);
System.out.println(findClosestMatch(usrInput.toLowerCase()));
}

Related

How to create custom exception for just Integers

I want to create a class that will serve me as an exception. I will give you two examples of how I tried. I've been looking for it but I can't find an example of how to put this into practice, or it doesn't work for me.
This is my method where user choose flight by ID, I want to throw an exception if a program user enters a String.
Code:
#Override
public void choosePassenger(ArrayList<Passenger> passengerList) {
System.out.println("Choose passenger by ID: ");
try {
int pickedPassenger = scanner.nextInt();
for (Passenger tempUser : passengerList) {
if (pickedPassenger == tempUser.getId()) {
System.out.println("You picked passenger: " + tempUser.getFirstName() + ", "
+ tempUser.getLastName() + ". Balance is: " + tempUser.getBalance());
selectedPassenger = tempUser;
break;
}
}
} catch (InputMismatchException e) {
System.out.println("Wrong input! Try again");
scanner.nextLine();
}
}
I tried on that way but after program show me message Wrong input! Try again it goes to another method not giving me chance to enter valid input
Also, how I can create exception here for just Strings?
System.out.print("Add name of passenger: ");
passenger.setFirstName(scanner.nextLine());
This is part of code that enable program user to create new user, he is adding here name, I want to create exception so if program user add integer for name I want to show him an exception
EDIT:
If I delete scanner.nextLine(); program stops but first print me my own exception message then print me message from next method and then InputMissMatchException for that method on his own because I input string instead of integer
If you want the user to try again, you can keep them in an infinite loop that breaks after correct input.
Editing as per #DevilsHnd observation. You cannot use scanner.nextInt() in this manner as it will read without user being prompted for input and it results in being stuck in an infinite loop.
You can then use nextLine() and validate the input is a number like this:
while(true) {
try {
int pickedPassenger = Integer.parseInt(scanner.nextLine());
} catch (NumberFormatException e) {
System.out.println("Wrong input! Try again");
}
}
For restricting input to a non numeral value as you want for the name, you would have to check if the value entered is a number (there is no scanner method to restrict reading to non numeral values)
Most elegant way in my opinion is to use an external library that has this like Apache Commons:
while(true) {
String firstName = scanner.nextLine();
if (!NumberUtils.isCreatable(firstName )) {
passenger.setFirstName(firstName );
break;
} else {
System.out.println("Value cannot be a number!");
}
}
However, if you cannot import external libraries, simplest way to do this is by using built in Java Integer.parseInt() function(although you might want to consider regex - see link below):
while(true) {
String firstName = scanner.nextLine();
try {
Integer.parseInt(firstName);
System.out.println("Value cannot be a number!");
} catch (NumberFormatException e) {
passenger.setFirstName();
break;
}
}
For more options on checking if a value is a number (like regex) check this:
https://www.baeldung.com/java-check-string-number

Return to previous spot in loop after try catch?

} else if (selectionKey == 2) {
System.out.println("Please enter the item name");
if (s.nextLine() != "") {
item = s.nextLine();
}
try {
ZybezChecker zb = new ZybezChecker(item);
zb.getAveragePrice();
System.out.println(zb.toString());
} catch(Exception e) {
System.out.println("Something went wrong. Perhaps an invalid item name?");
}
That's my code atm. How do I return back to the if statement and continue the loop after it catches?
You could embed it in a loop like,
for (;;) { // <-- start an infinite loop
System.out.println("Please enter the item name");
if (s.nextLine() != "") {
item = s.nextLine();
}
try {
ZybezChecker zb = new ZybezChecker(item);
zb.getAveragePrice();
System.out.println(zb.toString());
break; // <-- terminate the infinite loop.
} catch(Exception e) {
System.out.println("Something went wrong. Perhaps an "
+ "invalid item name?");
e.printStackTrace(); // <-- tell them what went wrong.
}
}
I think (if I understand your question and code correctly) that what you want is a loop containing the s.nextLine(). Note that I am assuming several things here:
s is a Scanner or something equivalent that reads input from the user
an exception is thrown if the user enters invalid input
you want to keep asking the user for input until they enter something valid
If this is the case, then you should create a loop like this:
while (true) {
System.out.println("Please enter the item name");
if (s.nextLine() != "") {
item = s.nextLine();
}
try {
ZybezChecker zb = new ZybezChecker(item);
zb.getAveragePrice();
System.out.println(zb.toString());
break;
} catch(Exception e) {
System.out.println("Something went wrong. Perhaps an invalid item name?");
}
}
Also, why are you calling nextLine() twice? When you call it the first time, it will read a line from the scanner. When you call it again, it will not return the same line; it will instead wait for a new line. This means the user has to enter some random string, then enter the actual value. Finally, you should NEVER use == or != on Strings. Since they are reference types, you are essentially checking if they occupy the same location in memory, rather than if they are equal. Use s.nextLine().equals("") instead.

Why do I get a "No line found" Exception in this code?

The following method causes a No line found Exception:
private static String getRebaseAnswer(boolean isFirst, boolean isLast) {
System.out.println("Would you like to (c)ontinue, (s)kip this commit, or"
+ " change this commit's (m)essage?");
Scanner in = new Scanner(System.in);
String answer;
while (true) {
answer = in.nextLine(); // <--- This Line
if (answer.equals("c") || answer.equals("m")) {
in.close();
return answer;
} else if (answer.equals("s") && !isFirst && !isLast) {
in.close();
return answer;
} else {
System.out.println("Would you like to (c)ontinue, (s)kip this commit, or"
+ " change this commit's (m)essage?");
}
}
}
I am calling the method in this method:
...
String answer;
Scanner in;
currHead = branchHeads.get(arg);
while (toRebase != null) {
System.out.println("Currently replaying:");
toRebase.getNode().printInfo();
answer = getRebaseAnswer(isFirst, toRebase.getParent() == null); // <--- This Line
...
What is causing the error?? Shouldn't the scanner wait for me to input a line before continuing the getRebaseAnswer method? A different method in my code has the exact same structure as the above method and encounters no problems. I've checked multiple other posts about this problem but their suggestions are all not pertinent to this problem or do not solve it.
This method runs with no problems:
private static boolean handleDangerous() {
System.out.println("Warning: The command you entered may alter the files in your"
+ " working directory. Uncommitted changes may be lost. Are you sure you"
+ " want to continue? (yes/no)");
Scanner in = new Scanner(System.in);
String answer;
while (true) {
answer = in.nextLine();
if (answer.equals("yes")) {
in.close();
return true;
} else if (answer.equals("no")) {
in.close();
return false;
} else {
System.out.println("Not a valid answer, please enter (yes/no).");
}
}
}
When you create a scanner connected to System.in and close it, you also close System.in. Therefore, subsequent attempts to read from System.in will result in the exception you observe.
The way is avoid this is to create the Scanner only once, and never close it until your program is finished. This Scanner should be passed to whichever function needs to read from System.in.
don't close scanner otherwise Stream will also be closed.
in.close();
remove this line from current location and put it in main method at the end so after all the operation stream will be closed..
You might be calling some other method which have already closed the stream and then you are calling this method.

Java bufferreader crashes on ctrl z

I'm making a game which plays until the user enters quit in the command line.
The user can enter different commands like get and go, with the get command the user can say what to get like, get baseball bat. What I do in my code is split the command.
everything is working fine but I have found a bug which I can't solve. If I enter "get" and press space and then ctrl+z it gets in a while loop which never ends.
It only happens with ctrl+z (1 time with ctrl c but after that 1 time not anymore)
private void run()
{
while (! quitCommand)
{
String input = null;
try
{
input = null;
System.out.println("Input "+ input);
System.out.println("Give a command.");
BufferedReader is = new BufferedReader(new InputStreamReader(System.in));
input = is.readLine();
handleCommand(input);
// As long as the command isn’t to quit:
// get the next input line and handle it. (With handleCommand.)
}
catch (Exception e)
{
System.out.println("Something went wrong we are sorry try again.");
e.printStackTrace();
}
}
}
/**
* #param userInput (This is the entire input string from the user.)
*
* (Tell others to) Perform the task which belongs to the given
* command.
*/
private void handleCommand(String userInput)
{
// Split the user input string.
if (userInput != null) // user input can not be empty
{
String[] delenTekst = userInput.split(" ");
// The first word is a command. The rest is extra information
String command = delenTekst[0];
String extra = "";
for (int i = 1; i < delenTekst.length; i ++)
{
if (i == 1)
{
extra = extra + delenTekst[i];
}
else
{
extra = extra +" " + delenTekst[i];
}
}
switch (command)
{
// Check if the command is to travel between rooms. If so, handle
case "go"
:
this.checkRoomTravel(extra);
break;
// If there isn't any room travel, then check all other command
case "get"
:
System.out.println("Looking for " +extra );
this.handleGetCommand(extra);
break;
case "quit"
:
quitCommand = true;
break;
default
:
System.out.println("Command is not known try help for information");
break;
}
}
else
{
userInput = "help";
}
}
I'm new to java so it can be something really simple.
On the top of my script I have a private boolean quitCommand = false; which is to check if the user entered quit.
Ctrl+Z closes the Console and therefore your readLine() returns null as pretended to indicate that end of file was reached. So all you need to do, is to check for null returned by readLine() and handle this as you handle the "quit".
I've changed your code (just to test my thesis) and also stream lined a few things, e.g. you dont need to recreate a BufferedReader every time you read a line.
private boolean quitCommand = false;
private void runIt() {
BufferedReader is = new BufferedReader(new InputStreamReader(System.in));
String input = null;
while(!quitCommand) {
try {
System.out.print("Give a command: ");
input = is.readLine();
// As long as the command isn’t to quit:
if(input == null || "quit".equals(input.trim())) quitCommand = true;
if(quitCommand) break;
// get the next input line and handle it. (With handleCommand.)
String[] words = input.trim().split("\\s+");
// ** This is the original handleCommand line **
System.out.println(input + ":" + Arrays.toString(words));
}
catch (Exception e) {
System.out.println("Something went wrong we are sorry try again.");
e.printStackTrace();
}
}
}
BTW: To split the input into words I'd use the regular expression as shown in my code. This works also if the user enters tabs or multiple spaces.
On DOS/Windows Ctrl+Z means end of input. This causes readLine() to return null no matter how many times you call it. This is likely to cause your code to fail as you don't appear to check for it. I suspect you are getting a NullPointerException which you are pretending didn't happen and trying again, endlessly.

How to show an error when wrong input is given

I wrote this code for hiding and unhiding any files or folders but how to show an error when user gives wrong input, I tried using else if but with wrong logic code, I want to show error when ever user gives wrong input while selecting to hide or unhide and if user gives wrong path to hide or unhide files.
import java.io.*;
class k
{
public static void main(String args[])
{
String a,h;
boolean q=true;
while(q==true){
try{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.print("\nunhide/hide/exit (u/h/e): ");
h=br.readLine();
if("hide".equalsIgnoreCase(h)){
System.out.print("\nwhat you want 2 hide: ");
a=br.readLine();
if(a.equals(a)){
Runtime r=Runtime.getRuntime();
Process p=r.exec("cmd.exe /c attrib +h "+a);
System.out.print("HIDDEN SUCCESSFULLY");
}
//else if(!a.equals(a)){System.out.print("error");}
}else if("unhide".equalsIgnoreCase(h)){
System.out.print("what u want to unhide: ");
a=br.readLine();
if(a.equals(a)){
Runtime r=Runtime.getRuntime();
Process p=r.exec("cmd.exe /c attrib -h "+a);
}
System.out.print("UNHIDDEN SUCCESSFULLY");
}
else if("exit".equalsIgnoreCase(h)){
System.exit(1);
}
}catch(Exception e){
System.out.println(e);
}
}
}
}
First: You make the user choose from 3 letters (h, u, e),
so you need to sure that the user enter "h" not "hide" , so your check need to be
if ("h".equalsIgnoreCase(h)) //h not hide {
.....
}
second : Its easy to check if the path you entered is exist or not , so if it's wrong you can know that , like this :
if (new File(a).exists()) {
Process p = r.exec("cmd.exe /c attrib +h " + a);
System.out.print("HIDDEN SUCCESSFULLY " + p);
} else {
System.out.println("wrong input");
}
Validating option selection
You're 90% of the way there with the first error message, remember if you have a series of if{} else if{} else if {}else{} then anything that doesn't fit in the ifs will end up in the else. So
if("hide".equalsIgnoreCase(h)){
System.out.print("\nwhat you want 2 hide: ");
a=br.readLine();
if(a.equals(a)){ //<-----a.equals(a) is not valid validation!
Runtime r=Runtime.getRuntime();
Process p=r.exec("cmd.exe /c attrib +h "+a);
System.out.print("HIDDEN SUCCESSFULLY");
}else{
System.out.println("Invalid Input");
}
}
}else if("unhide".equalsIgnoreCase(h)){
System.out.print("what u want to unhide: ");
a=br.readLine();
if(a.equals(a)){
Runtime r=Runtime.getRuntime();
Process p=r.exec("cmd.exe /c attrib -h "+a);
}
System.out.print("UNHIDDEN SUCCESSFULLY");
}else if("exit".equalsIgnoreCase(h)){
System.exit(1);
}else{
System.out.println("Invalid Input");
}
This will give an error message on entering a non valid option, but your existing validation of the file name is not correct so an error message for that cannot be generated without a definition of "incorrect".
Path validation
I'm guessing invalid is anything that triggers that catch block so move the try catch inside the loop and use it to validate the input;
if("hide".equalsIgnoreCase(h)){
System.out.print("\nwhat you want 2 hide: ");
a=br.readLine();
try{
Runtime r=Runtime.getRuntime();
Process p=r.exec("cmd.exe /c attrib +h "+a);
System.out.print("HIDDEN SUCCESSFULLY");
}catch(Exception e){
System.out.print("Invalid path");
}
}
Other points
As discussed in the comments if(a.equals(a)) will always be false. Whatever a is, it intrinsically is itself

Categories

Resources