(Java) Exiting While Loop In Switch Case With Empty Line - java

To briefly explain, I'm supposed to get the user to enter the name of the
recipient of a message, and then get them to enter the message body, which can
have multiple lines. If they enter a blank line, then the message body ends and
they can select another case in the switch.
case 'S':
case 's':
if(user.equals(" ")) {
System.out.println("No user logged in.");
} else {
System.out.println("Recipient: ");
recip = menuScan.next();
m = new Message(user,recip);
System.out.println("Enter message. Blank line to quit.");
mbody = menuScan.nextLine();
while(!mbody.equals("")) {
mbody = menuScan.next();
m.append(mbody);
}
ms.deliver(m);
System.out.println("Messgae sent.");
}
break;
But as it is now, the while loop is skipped completely. I've tried changing recip to menuScan.nextLine(), and mbody to menuScan.next() and .nextLine(), but the only other thing that happens is the message body goes on forever.
I've also tried using two different Scanner objects for recip and mbody, but no luck there, either.

You should replace your next by nextLine. next, as the documentation states, returns the next token if it matches the pattern constructed from the specified string, which is not what you want.
Try the following:
System.out.println("Recipient: ");
recip = menuScan.nextLine();
m = new Message(user,recip);
System.out.println("Enter message. Blank line to quit.");
mbody = menuScan.nextLine();
while(!mbody.equals("")) {
m.append(mbody);
mbody = menuScan.nextLine();
}
ms.deliver(m);
System.out.println("Messgae sent.");

I've tried this piece of your code
System.out.println("Enter message. Blank line to quit.");
mbody = menuScan.nextLine();
while (!mbody.equals("")) {
mbody = menuScan.next();
m.append(mbody);
}
changing it a bit
System.out.println("Enter message. Blank line to quit.");
mbody = menuScan.nextLine();
while (!mbody.equals("")) {
m.append(mbody);
mbody = menuScan.nextLine();
}
This way the loop is executed and exited as expected.
I have used java.util.Scanner

Related

java.util.NoSuchElementException when reading user input in switch statement

Running into an error with this project I'm working on for a computer science course, and hoping someone can give me insight into what may be happening. A bit of background to what's occurring in the code:
In the below code, I have the start of my program which displays a UI menu and asks for user input and uses a switch statement to run appropriate methods based on user input.
/**
* Start of program
*/
public static void main(String[] args) {
Library library = new Library();
char userChoice; //Stores what menu item the user chose
Scanner userMenuChoiceScanner = new Scanner(System.in);
boolean loop = true;
displayMenu(); //Displays main UI menu
userChoice = Character.toLowerCase(userMenuChoiceScanner.nextLine().charAt(0)); //Gets user's menu choice
/*Loops UI menu afer user has made menu choice and exits loop if user choses 'q' from menu.*/
while(loop) {
/* Switch descides what menu choice user has made and whether to prin menu UI again, load,
* search, print, or analyze a music catalog, or to quit program.
*/
switch(userChoice) {
case 'm':
System.out.println();
displayMenu();
userChoice = Character.toLowerCase(userMenuChoiceScanner.nextLine().charAt(0));
break;
case 'p':
System.out.println();
if(library.getBooks().size() != 0) {
printLibrary(library);
} else {
System.out.println("There are no books in the library. Please add a book first.");
}
System.out.print("Please enter a command (press 'm' for Menu):");
userChoice = Character.toLowerCase(userMenuChoiceScanner.nextLine().charAt(0));
break;
case 'a':
System.out.println();
addBookToLibrary(library);
System.out.print("Please enter a command (press 'm' for Menu):");
userChoice = Character.toLowerCase(userMenuChoiceScanner.nextLine().charAt(0));
break;
case 'd':
System.out.println();
if(library.getBooks().size() != 0) {
deleteBookFromLibrary(library);
} else {
System.out.println("There are no books in the library. Please add a book first.");
}
System.out.print("Please enter a command (press 'm' for Menu):");
userChoice = Character.toLowerCase(userMenuChoiceScanner.nextLine().charAt(0));
break;
case 'r':
System.out.println();
if(library.getBooks().size() != 0) {
readBookFromLibrary(library);
} else {
System.out.println("There are no books in the library. Please add a book first.");
}
System.out.print("Please enter a command (press 'm' for Menu):");
userChoice = Character.toLowerCase(userMenuChoiceScanner.nextLine().charAt(0));
break;
case 'q':
System.out.println();
System.out.println("Thank you! Goodbye!");
loop = false;
break;
default:
System.out.println();
System.out.println("Invalid selection!");
System.out.print("Please enter a command (press 'm' for Menu):");
userChoice = Character.toLowerCase(userMenuChoiceScanner.nextLine().charAt(0));
System.out.println();
}
}
userMenuChoiceScanner.close();
}
What's occuring is when tthe user makes a choice, it goes into the appropriate methods and fulfills it's tasks there, then when it returns to the switch statement to get a new user input, it throws a java.util.NoSuchElementException error as if the scanner stream was closed, but I don't close the scanner until the end (the stream should still be open).
The switch statement is set up in a way where a book must be added (the user must chose 'a' first) before any other option can be chosen. Here is the code to he addBookToLibrary() method which has a couple scanners which are opened and closed. I assume maybe closing out these scanners may be causing the issue?
/**
* Adds new book to library
* #param library ArrayList object which holds book objects
*/
public static void addBookToLibrary(Library library) {
Scanner addBookScanner = new Scanner(System.in);
String title = "";
String author = "";
String genre = "";
String filename = "";
boolean addStatus = false;
/*Asks user for book details */
System.out.println("Enter the details of the book you want to add to the library:");
System.out.println("What is the book title?");
title = addBookScanner.nextLine();
System.out.println("What is the author's name?");
author = addBookScanner.nextLine();
System.out.println("What is book genre?");
genre = addBookScanner.nextLine();
System.out.println("What is the book's filename?");
filename = addBookScanner.nextLine();
addBookScanner.close();
Book newBook = new Book(author, title); //creates new book with author and title set
newBook.setGenre(genre); //sets book genre
File bookFile = new File(System.getProperty("user.dir") + '\\' + filename); //used to check if file user provided exists
System.out.println(bookFile);
/*Checks to see if file user provided actually exists*/
if(bookFile.exists()) {
try {
newBook.setFilename(filename);
}catch(Exception e) {
}
}
else {
Scanner getNewFilenameScanner = new Scanner(System.in);
//Continues to ask user for new filename if file doesn't exist
do {
System.out.println("I'm sorry, but the file you specified does not exist.");
System.out.print("Enter a new file name:");
bookFile = new File(getNewFilenameScanner.nextLine());
}while (!(bookFile.exists()));
getNewFilenameScanner.close();
}
addStatus = library.addBook(newBook); //adds book to library
if(addStatus) {
System.out.println("Book was successfully added!");
}
else {
System.out.println("Book was not successfully added. Please try again.");
}
}
This code worked perfectly in a previous project, so I'm not certain why it's not working now. Any help would be greatly appreciated.
Thank you so much
In your addBookToLibrary method, you close the Scanners after you are done using them. However, those scanners are connected to System.in, the standard input stream. Closing those scanners will also close the standard input stream, according to the documentation.
What else is connected to the standard input stream? userMenuChoiceScanner! After the standard input stream is closed, userMenuChoiceScanner can't read from it, hence throwing an exception.
Note that although userMenuChoiceScanner is not closed until the very end, the stream that it is reading from is closed.
In fact, you don't need to create multiple scanners here. You only need to use one scanner, and pass it around to different methods. For example, addBookToLibrary could accept a Scanner:
public static void addBookToLibrary(Library library, Scanner s) {
And it will only use s to read inputs. You can pass your userMenuChoiceScanner to it:
addBookToLibrary(library, userMenuChoiceScanner);
As a general rule, you should not close anything that is not opened by you. You didn't open the standard input stream (the JVM did), so you shouldn't close it.

How to validate input string using while loop

I know this might seem like a simple/silly question, but I am trying to keep my code as organized and simple as possible. The problem that I am having is with a while loop for validation. I am validating a string input. I am using the validation simply to make sure that something is entered. The only time I would like the while loop to run is when no information is entered at all, so I would like to include every character and symbol. The question that I have, is that I am wondering if there is a shorter way to include every character possible except for simply hitting enter of course. Here is the simple code snippet.
Scanner input = new Scanner(System.in);
PrintWriter out = new PrintWriter("contactRequest.txt");
System.out.print("Please enter your name: ");
String email = input.nextLine();
while(!email.matches("[a-zA-Z]+"));
{
System.out.println("\nPlease enter a valid E-Mail.");
email = input.nextLine();
}
out.println("E-Mail: " + email);
What about restructuring it as a do-while and only having one print/scan?
Scanner input = new Scanner(System.in);
PrintWriter out = new PrintWriter("contactRequest.txt");
String email;
String prompt = "Please enter your name: ";
do {
System.out.print(prompt);
email = input.nextLine();
prompt = "\nPlease enter a valid E-Mail.\n"
} while (!email.matches("[a-zA-Z]+"));
out.println("E-Mail: " + email);

Java - Reading multiple console input strings into a variable

I've searched around and can't find a solution to my problem. For one of my courses I'm tasked with writing a simple console email system. When the user is prompted for a message body, the string variable that holds the input only takes one word, not the whole message. I read that I should use readLine(), but when the program prompts the user to enter a message body, it completely skips input for that segment. To remedy this, I read that I should place a skip("\n") before I read the line. Now, however, the program doesn't end after the user presses Enter. It just keeps taking input and won't let me do anything.
Here is a bit of the code to help:
Scanner in = new Scanner(System.in);
//Declare variables
String subject, reciepent, message = "";
//Get subject
System.out.println("> Enter subject: ");
subject = in.next();
//Get reciepent
System.out.println("> Enter reciepent: ");
reciepent = in.next();
//Get message
System.out.println("> Enter message: ");
in.skip("\n");
message = in.nextLine();
//Print out message to verify user input
System.out.println("> " + message);
I don't understand how nextLine() works for all the threads I searched, but not for me.
The solution to this problem is not to use the .skip() method, but use .nextLine() instead, which removes the trailing '\n' character from the input stream as you desire.
So change the line: in.skip("\n"); to in.nextLine();
Try using nextLine() which waits for user input and then returns the input. Your code should be like this:
Scanner in = new Scanner(System.in);
//Declare variables
String subject, recipient, message;
//Get subject
System.out.println("> Enter subject: ");
subject = in.nextLine();
//Get recipient
System.out.println("> Enter reciepent: ");
recipient = in.nextLine();
//Get message
System.out.println("> Enter message: ");
message = in.nextLine();
//Print out message to verify user input
System.out.println("> " + message);
How about
Scanner s = new Scanner(System.in);
String line = "";
while((line = s.nextLine()) != null) {
System.out.println("> Enter subject: ");
subject = in.nextLine();
//Get recipient
System.out.println("> Enter reciepent: ");
recipient = in.nextLine();
//Get message
System.out.println("> Enter message: ");
message = in.nextLine();
//Print out message to verify user input
System.out.println("> " + message);
}

Searching for a string in a text file using Java

I am trying to make the user input an Airport Name, and the program will search from a text file to get the matching Code, right now I only need it to read the line. I have looked into many similar questions in here, but nothing works for me. The program return the else result rather than the found result.
This is my code so far
public static void main (String[] args) throws IOException
{
File file = new File("codes01.dat");
Scanner myFile = new Scanner(file);
Scanner kb = new Scanner(System.in);
String line;
System.out.println("Hey man, this is totally leigt, just enter an Airport code and I'll hook you up.");
System.out.print("First, y'all need to give me the file name: ");
String fileName = kb.nextLine();
if (fileName.equalsIgnoreCase("codes01"))
{
System.out.print("Cool, now give me your Airport Name: ");
String AirportName = kb.nextLine();
while (myFile.hasNextLine())
{
line = myFile.nextLine();
String name = myFile.next();
System.out.println(line);
if(name.equalsIgnoreCase(AirportName))
{
System.out.println("IT'S WORKING, I DON'T KNOW HOW BUT IT IS "+line);
break;
}
else
{
System.out.println("Sorry, dude, ain't no airport in my VERY limited list with that name");
break;
}
}
}
The program return the else result rather than the found result.
That is because you are breaking out of the loop after testing the first line in your file.
Look carefully at your code ... in context.
if(name.equalsIgnoreCase(AirportName)) {
System.out.println("It is working");
break;
} else {
System.out.println("Sorry");
break; // What????
}
Why are you using the break statement in the if-else block? Try to get rid of the break statement and then execute your code.
if(name.equalsIgnoreCase(AirportName))
{
System.out.println("The name of Airport matches");
}
else
{
System.out.println("Sorry No Match Found");
}
Look closely at these two lines. There's a problem there. Step through the code in your head pretending you are the Scanner class.
line = myFile.nextLine();
String name = myFile.next();

String to int conversion with input from Scanner

I am trying to convert a string value taken from the keyboard into an int value. I have done it like this before but now I am getting an error which states NumberFormatException.forInputString
Scanner input = new Scanner(System.in);
String choice = "";
int numberChoice;
System.out.println("Please select one of the following options");
choice = input.nextLine();
numberChoice = Integer.parseInt(choice); /*I am getting the error on this line*/
The input code is:
Data[] temperatures = new Data[7];
for(int i = 0; i < temperatures.length; i++)
{
System.out.println("Please enter the temperature for day " + (i+1));
temperatures[i] = new Data(input.nextDouble());
}
you can use numberChoice = input.nextInt(); instead of choice = input.nextLine(); and then convert the string into integer
When you use a Scanner method that looks at one token, such as nextDouble() or nextInt(), the scanner will consume the characters in that token, but it will not consume the newline character at the end of the line.
This is fine if the next Scanner call is to another nextDouble(), nextInt(), etc., because then that call will skip over the newline.
However, if the next call is nextLine(), it will return "". nextLine() will return everything up to the next newline character; and since it hasn't yet consumed the newline character after the nextDouble() call, it will stop at that newline, and return an empty string, without giving you a chance to enter another line.
To solve this, you need to call an extra nextLine() to consume the newline:
for(int i = 0; i < temperatures.length; i++)
{
System.out.println("Please enter the temperature for day " + (i+1));
temperatures[i] = new Data(input.nextDouble());
}
input.nextLine(); // Add this to consume the newline
String choice = "";
int numberChoice;
System.out.println("Please select one of the following options");
choice = input.nextLine();
numberChoice = Integer.parseInt(choice);
Make sure you don't accidentally type in a space or a non-numeric character in your input line. I ran your code snippet and it works just fine.
Please select one of the following options
6546a
Exception in thread "main" java.lang.NumberFormatException: For input string: "6546a"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at PrimeNumbers.main(PrimeNumbers.java:12)
This should work fine, assuming you enter something that can be parsed as an int.
Wrap the offending line in a try block and output the error and the contents of choice to see what's going wrong
for example, try this:
try {
numberChoice = Integer.parseInt(choice);
}
catch (NumberFormatException nfe){
System.out.println("Failed to parse: ##"+choice+"##"); // mark off the text to see whitespace
}
on my machine, this produces
/Users/jpk/code/junk:521 $ java SO
Please select one of the following options
two
Failed to parse: ##two##

Categories