Text message abbreviation decoder: NoSuchElementException - java

I need help developing my text message abbreviation decoder I'm trying to put together. The first part of the program should do this: "If a user's input string matches a known text message abbreviation, output the unabbreviated form, else output: Unknown. Support two abbreviations: LOL -- laughing out loud, and IDK -- I don't know." Then: "Expand to also decode these abbreviations. BFF -- best friends forever, IMHO -- in my humble opinion and TMI -- too much information.
This is the code I have so far:
import java.util.Scanner;
public class TextMsgAbbreviation {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String textMsg = "";
{
String BFF = "best friends forever";
String IMHO = "in my humble opinion";
String TMI = "too much information";
String LOL = "laughing out loud";
String IDK = "i don't care";
System.out.println("Input an abbreviation:" + " ");
textMsg = input.next();
if (textMsg.compareTo("LOL") == 0) {
System.out.println(LOL);
} else if (textMsg.compareTo("IDK") == 0) {
System.out.println(IDK);
} else if (textMsg.compareTo("BFF") == 0) {
System.out.println(BFF);
} else if (textMsg.compareTo("IMHO") == 0) {
}
}
}
}
This is the output I get:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1371)
at TextMsgAbbreviation.main(TextMsgAbbreviation.java:17)
What am I doing wrong?

According to the Java API docs, the next() method throws a NoSuchElementException when there aren't any more tokens available to be read. So, it is recommended to call the hasNext() method before calling the next() method in Scanner class to make sure that there is a token available to be read. So, try something like below :
if(input.hasNext()) {
textMsg = input.next();
}
On a side-note, from Java 7 onwards, the switch statements can take a String input, so you may try using that in your code. In my personal opinion, it will be more readable than using the multiple if-else loops.
An example :
switch(textMsg) {
case "LOL" : System.out.println(LOL);
break;
case "IDK" : System.out.println(IDK);
break;
case "BFF" : System.out.println(BFF);
break;
case "IMHO": System.out.println(IMHO);
break;
default : System.out.println("Unknown");
}

The values displayed 862 1371 17 need to be typed into the input box.Below is working code for the problem.
import java.util.Scanner;
public class TextMsgDecoder {
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
String userInput;
System.out.println("Enter text:");
userInput = scnr.nextLine();
System.out.println("You entered: " + userInput);
if(userInput.indexOf("BFF") != -1) {
System.out.println("BFF: best friend forever");
}
if(userInput.indexOf("IDK") != -1) {
System.out.println("IDK: I don't know");
}
if(userInput.indexOf("JK") != -1) {
System.out.println("JK: just kidding");
}
if(userInput.indexOf("TMI") != -1) {
System.out.println("TMI: too much information");
}
if(userInput.indexOf("TTYL") != -1) {
System.out.println("TTYL: talk to you later");
}
}
}

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

do while in Java doesn't work [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 4 years ago.
I have following do while code, where I am trying to end the loop when the text entered is Stop. However even though when I type Stop in the console, it doesn't work. I tried to debug it and see it tries to compare the Stop text but doesn't stops it. I don't understand what is the problem.
This is a java code running in eclipse.
import java.util.Scanner;
public class Application8_Switch {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter a string to match the output");
String text;
do {
text = input.nextLine();
switch (text) {
case "start":
System.out.println("Machine started");
break;
case "end":
System.out.println("This Machine stopped");
break;
default:
System.out.println("Command not recognized");
break;
}
} while (text != "Stop");
}
}
Try this:
Scanner input = new Scanner(System.in);
System.out.println("Enter a string to match the output");
String text;
do {
text = input.nextLine();
switch (text) {
case "start":
System.out.println("Machine started");
break;
case "end":
System.out.println("This Machine stopped");
break;
default:
System.out.println("Command not recognized");
break;
}
} while (!text.equals("Stop"));
Modifications:
Used !text.equals("Stop") because == checks by comparing references. However You need to use equals() method to check its content.
Strings in Java aren't compared using == or != like you think they would be.
Instead of using text != "Stop", use !text.Equals("Stop").

Boolean loop combined with JOptionPane Java

I would love to share my code. But in my university the code gets tested for "cheating".
But here is my code in simplier form.
public static String readin() {
boolean error = false;
do {
string stringin;
stringin = JOptionPane.showInputDialog(null, "Please enter a number");
switch (stringin.length()) {
case 0:
JOptionPane.showMessageDialog(null, "Error Please repeat");
error = true;
case 1:
return stringin;
}
return null;
} while (error == true);
}
This Code is really in it's simpliest form. I know that for this case it would be smarter to set the while to JOptionPane is empty or something. Since in my code are like 12 different error cases. I want to use the boolean. Please: the return null will never occur in the real code.
But the real problem I have: It works perfectly fine besides: if he repeats the loop he doesn't give me the chance to type a new stringin in.
How can i do this?
Also I am sorry for my faults in english.
EDIT:
All your helps fixed my problems! Thank you very much! I love this forum!
Try with break before case 1 (#Tuxxy_Thang) and remove return null; before while (error); and put after.
public static String readin(){
boolean error=false;
do{
string stringin;
stringin=JOptionPane.showInputDialog(null,"Please enter a number");
switch (stringin.length()){
case 0: JOptionPane.showMessageDialog(null, "Error Please repeat");
error=true;
break;
case 1: return stringin;
}
} while (error);
return null;
}
You dont have to check for while condition as you wanted the user to repeat again.Return only if you have the right value else ask again
public static String readin() {
while (true) {
String stringin = JOptionPane.showInputDialog(null, "Please enter a number");
switch (stringin.length()) {
case 0:
JOptionPane.showMessageDialog(null, "Error Please repeat");
break;//is important in switch cases
case 1:
return stringin;
}
}
}
There are two reasons:
The return null should be moved to end.
There should be a break statement at the end of the first case
I have given the modified code and it repeats the loop if the user does not enter anything for the JOptionPane:
public static String readin() {
boolean error = false;
do {
String stringin;
stringin = JOptionPane.showInputDialog(null,
"Please enter a number");
switch (stringin.length()) {
case 0:
JOptionPane.showMessageDialog(null, "Error Please repeat");
error = true;
break; // **added**
case 1:
return stringin;
}
} while (error == true);
return null; // Moved here. It will return if user entered more than 1 letter.
}
You are making a simple job hard, use Java classes properly and you will have an easier time of things
public static String readin()
{
Boolean gettingNumber = true;
String stringin = null;
while (gettingNumber)
{
stringin = JOptionPane.showInputDialog(null, "Please enter a number");
try
{
Integer number = Integer.parseInt(stringin);
gettingNumber = false;
}
catch (NumberFormatException exception)
{
// no need to do anything
}
}
System.out.println("returning [" + stringin + "]");
return(stringin);
}
I added this because I deduced that you are asking the user to input a number but your code would only allow the user ot enter any single character regardless of whether it is a valid digit or not and that is what you would return form your original 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.

Password masking does not terminate the program when needed

I developed the following application in which I needed to masking the PIN and terminate the program after the user has entered the wrong PIN thrice. However, the program terminates only if i close the stopThread at the beginning (I commented it in the code below), however the password masking does not occur for all the three channces when I do so. But, when I close the stopThread just before displaying the login successful screen, the program does not terminate. I need to use ctrl+c to end the program.
Any help is greatly appreciated.
boolean stopThread = false;
boolean hideInput = false;
boolean shortMomentGone = false;
public static double userBal=0.0D;
public void run(){
try{
sleep(500);
} catch(InterruptedException e){
}
shortMomentGone = true;
while(!stopThread){
if(hideInput){
System.out.print("\b*");
}
try{
sleep(1);
} catch(InterruptedException e){
}
}
}
public static final int NB_OF_TRIES = 3;
public void validatePin(){
BankAccount getAll=new BankAccount();
String pin="";
getAll.Login();
Login hideThread =new Login();
hideThread.start();
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
try{
do{
} while(hideThread.shortMomentGone == false );
// Now the hide thread should begin to overwrite any input with "*"
hideThread.hideInput = true; // Read the PIN
System.out.println("\nPIN:");
boolean pinMatch = false;
int i = 0;
while(!pinMatch && i < NB_OF_TRIES) {
hideThread.hideInput = true;
pin = in.readLine();
i++;
//hideThread.stopThread = true; //Program terminates after third attempt
//PIN masking is stopped, if uncommented
System.out.print("\b \b");
if(pin.equals(" ")){
System.out.println("Please do not leave unnecessary spaces!");
getAll.Login();
}else if(pin.equals("")){
System.out.println("Please do not press the enter key without entering the PIN!");
getAll.Login();
}
FileInputStream fileinputstream = new FileInputStream(".\\AccountInfo.txt");
DataInputStream datainputstream = new DataInputStream(fileinputstream);
BufferedReader bufferedreader1 = new BufferedReader(new InputStreamReader(datainputstream));
do
{
String s1;
if((s1 = bufferedreader1.readLine()) == null)
{
break;
}
if(s1.trim().charAt(0) != '#')
{
String as[] = s1.split(" ");
if(pin.equals(as[0]))
{
System.out.println("You have login!");
String s2 = as[2];
userBal = Double.parseDouble(s2);
getAll.balance = userBal;
hideThread.stopThread = true;
getAll.MainMenu();
System.exit(0);
}else if(pin != as[0]){
System.out.println("Invalid PIN!");
getAll.Login();
System.out.println("\n NOTE :- You are only allowed to enter the PIN THREE times. The number of tries remaining before your card is blacklisted are "+i + "\n Please re-enter your PIN");
}
}
} while(true);
datainputstream.close();
}//End of While Loop
}catch(Exception exception)
{
System.err.println((new StringBuilder()).append("Error: ").append(exception.getMessage()).toString());
}//End of try-catch block
}
There's a readPassword() method in java.io.Console, use that. Why do you need a separate thread at all? That makes everything way too complicated.
Regarding your question why this does not close: Java may optimize while(isTrue){} to something like if(isTrue) { while(true) { } } if you don't set isTrue volatile or synchronize the access to isTrue (getter/setter). This optimizations is called hoisting and explained in Effective Java SE, item 66.
Here is an article which explains exactly your problem: echoing * instead of blanks.
http://java.sun.com/developer/technicalArticles/Security/pwordmask/
They are going the complicated way, too but it works. I would prefer blanks over asterisks since that is the easier way to go. Not echoing * is *nix standard afaik.
Actually after I analysed it a but more i realized that the reason the system wont terminate is because it is not kept in the proper place. Therefore, the solution would be to end the program as soon as the while loop is closed and then everything would work fine.
} while(true);
datainputstream.close();
}//End of While Loop
System.exit(0); // After the system is closed the program would terminate after the third attempt
}catch(Exception exception)
{
System.err.println((new StringBuilder()).append("Error: ").append(exception.getMessage()).toString());
}//End of try-catch block

Categories

Resources