Hey Im taking coding lessons at school but the teacher does not explain that well so we have to look for info online which I did, but I was not able to find the error in my code, can you help me please?
char end='s';
do{
System.out.println("Tipo de boleto");
char boleto = (char) System.in.read();
switch (boleto){
case 'a':
System.out.println("El boleto cuesta $120.00");
System.out.println("Otro boleto (s/n)?");
end = (char) Integer.parseInt(entrada.readLine());
continue;
case 'n':
System.out.println("El boleto cuesta $75.00");
System.out.println("Otro boleto (s/n)?");
end = (char) Integer.parseInt(entrada.readLine());
continue;
case 'i':
System.out.println("El boleto cuesta $60.00");
System.out.println("Otro boleto (s/n)?");
end = (char) Integer.parseInt(entrada.readLine());;
continue;
default:
System.out.println("Error" );
break;
}
}
while (end == 'n');
Exception
run: Tipo de boleto a El boleto cuesta $120.00 Otro boleto (s/n)?
Exception in thread "main" java.lang.NumberFormatException: For input string: "" at
java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:592) at
java.lang.Integer.parseInt(Integer.java:615) at
asjidbhahsjksbd.Asjidbhahsjksbd.main(Asjidbhahsjksbd.java:16) Java Result: 1
BUILD SUCCESSFUL (total time: 7 seconds)
See, you are trying to parse "" as an Integer whichwill throw NumberFormatException. You have to check for null and isEmpty() in this order and then try to parse the string as an integer.
You are getting exception in this line , i think you are getting "" blank String from readLine() method
end = (char) Integer.parseInt(entrada.readLine());
So Do like this
String input=entrada.readLine();
if(input!=null && !input.equals(""))
{
end = (char) Integer.parseInt(input);
}
I suggest you to use google guava libraries which is having a utility function
Strings.isNullOrEmpty(inputString)//Checks String for both null and empty
Update
As #ajb suggested :
If you want to convert s and n into character than don't use your code snippet
instead of Parsing an Integer
Use
char c=input.charAt(0);
you should replace continue statement with a break. putting continue will skip the current iteration and the while condition will not be evaluated.
This does not do what you think it will:
end = (char) Integer.parseInt(entrada.readLine());
This line reads a string. It then assumes the string is a number, and determines the number. If the user actually enters "s" or "n", it throws an exception, because "s" and "n" are not numbers. The number is then treated as the ASCII value of a character. The result is that the loop will test whether the user types in the string "110", since 110 is the ASCII value of the character n.
There are several ways to fix this; here's one:
end = entrada.readLine().charAt(0);
This returns the first character of whatever line the user types in. This is a sloppy solution because it doesn't work if the user hits ENTER on an empty line (it will throw an exception). Better:
String answer = entrada.readLine();
if (answer.isEmpty()) {
end = 'n'; // treat an empty string like 'n'
} else {
end = answer.charAt(0);
}
Also, I think the while might be wrong. while (end == 'n') means the program will loop back if the user enters n, which I think is the opposite of what you want.
P.S. There are other errors that I didn't catch, that others have pointed out; using continue is wrong--use break to leave the switch statement. And reading one character with System.in.read() is a problem, because the user will type in a character, but the character won't get into the program until the user types ENTER, and then readLine() will get the rest of this first line, instead of asking for another line. But I usually don't use System.in.read() so I'm not completely sure what this does without trying it.
Related
EDIT: I figured it out! I got rid of the try-catch block because it just didn't work the way I wanted it to. The code below is my final one. Thank you to everyone who responded to this question.
I am trying to code a to-do list program. One function of this program is to search for the entries inside the string array. The user should only input a ONE WORD keyword so if the user inputs more than one word or none, a prompt should show telling the user to try again. The code I've written so far is inside a try-catch statement. Using next() scanner only takes the first word and disregards the rest when inputting a multiple-word keyword, instead of producing an Exception. Here is my code for it:
case 2:
String searchKeyword;
int success = 0;
while(success==0) {
System.out.print(">> Enter 1 keyword: ");
searchKeyword = sc.nextLine();
String splitSearchKeyword[] = searchKeyword.split(" ");
if (splitSearchKeyword.length == 1) {
if(Quinones_Exer2.searchToDoList(searchKeyword, todoList)==-1) {
System.out.println(">> No item found with that keyword!");
System.out.println();
}
else {
System.out.println(">> Found one item!");
System.out.println("("+(Quinones_Exer2.searchToDoList(searchKeyword, todoList)+1)+")"+" "+todoList[Quinones_Exer2.searchToDoList(searchKeyword, todoList)]);
System.out.println();
}
success++;
}
else {
System.out.println(">> Please input a single word keyword!");
System.out.println();
}
}
break;
}```
Use Scanner.nextLine() then split the supplied string. If the length of array is greater than 1 or the supplied string is empty then issue an invalid entry message and have the User enter the string over again:
while(tries2 == 0) {
searchKeyword = "";
while (searchKeyword.isEmpty()) {
System.out.println("Enter 1 keyword: ");
searchKeyword = sc.nextLine().trim();
if (searchKeyword.isEmpty() || searchKeyword.split("\\s+").length > 1) {
System.out.println("Invalid Entry! {" + searchKeyword
+ "You must supply a single Key Word!");
searchKeyword = "";
}
}
tries2++;
// ... The rest of your code ...
}
From the docs of Scanner.next():
Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern.
You would need to call next() again to get the the rest of the input.
Much simpler would be to use Scanner.nextLine() to get entire line and then use String.split() with whatever delimiter you are using to get an array of all inputted keywords.
Edit: Scanner.next(pattern) may do what you are looking for. It throws InputMismatchException if the input does not match provided pattern(regex). Example:
scanner.next("^[a-zA-Z]+$")
This requires the entire line to consist of lower and/or upper case letters and nothing else.
I don't understand how the nested do-while loop could discard other characters and why is there a newline syntax. Could some one explains it, many thanks.
public class guessGame {
public static void main(String[] args) throws java.io.IOException{
char ch, ignore,answer='K';
do {
System.out.println("I'm thinking of a letter between A and Z.");
System.out.print("Can you guess it:");
//read a character
ch=(char) System.in.read();
// ************ here ************
do {
ignore =(char) System.in.read();
} while (ignore != '\n');
// ************ to here ************
if (ch==answer) System.out.println("** Right **");
else {
System.out.print("...Sorry, you're ");
if(ch<answer) System.out.println("too low");
else System.out.println("Too high");
System.out.println("Try again\n");
}
} while (answer !=ch);
}
}
Input from the user until newline char is read and first char from the input is assigned to ch with this line:
ch=(char) System.in.read();
After that, rest of the input user entered is assigned to ignore variable. New line syntax basically tells the program that this is the last char from input stream.
After first char from the input is assigned to ch, code block inside do statement is executed once. If the second char user typed is \n, while statement becomes false and program continues to execute from next line of code. If the second char typed is not newline char, loop continues until newline char.
Why is it needed?
ch=(char) System.in.read();
//user enters ASDF\n
//ch is assigned as A
do {
ignore =(char) System.in.read();//SDF\n is assigned to ignore
} while (ignore != '\n');
If the inner do while above wouldn't exist, the outer loop would automatically assign SDF\n (including newline char) to ch from input stream one by one in every loop and each would be regarded as an answer from the user until input stream has no more chars left.
I don't have enough reputation to reply in the comment.
The code which you has written above will get completed only when you are giving character 'K'. Inner do while is to skip the if-else statement when the character is /n.
Only when you are giving character 'K', the outer do-while will get satisfied and get completed.
For example -
input character is 'A' - It will print sysout statements and once again wait for the new input.
input character is '/n' - It won't print any sysout. But, it will wait for the new input.
input character is 'K' - It will print sysout as right and get completed.
Your program behave in this way (in English):
Step 1 : accept a character followed by an Enter key (the newline character).
Step 2 : if the character input is not answer, return to Step 1
Step 3 : print ** Right **
Now, there are two reasons the do ... while loop you mentioned is there.
First reason, user can type "abcdef" followed by an enter key.
For this case, the program only wants to take the first character 'a' to compare with answer. The rest are to be discarded. The do ... while is there to ignore "bcdef".
Second reason, in certain operating system, all linefeed ('\n') is proceeded by the carriage return ('\r'). For this case, one needs to ignore the carriage return.
public class guessGame {
public static void main(String[] args) throws java.io.IOException{
char ch, ignore,answer='K';
do {
System.out.println("I'm thinking of a letter between A and Z.");
System.out.print("Can you guess it:");
//read a character
ch=(char) System.in.read();
// Case 1 : assume user input "abcdef\n" here
// Case 2 : assume operating system makes user input "a\r\n"
// ************ here ************
do {
ignore =(char) System.in.read();
// Case 1 : "bcdef\n" is read in this loop
// Case 2 : "\r\n" is read in this loop
} while (ignore != '\n');
// Case 1 : "bcdef" is ignored
// Case 2 : "\r" is ignored
// ************ to here ************
if (ch==answer) System.out.println("** Right **");
else {
System.out.print("...Sorry, you're ");
if(ch<answer) System.out.println("too low");
else System.out.println("Too high");
System.out.println("Try again\n");
}
} while (answer !=ch);
}
}
this is my first time asking a question. If I'm breaking any rules let me know please :)
I want to verify that the user only types in only one character and store in a variable I have already declared initially. As well, loop back the question for user to type in again if they did not do what they are asked for
Here is a what I have done so far
import java.util.Scanner;
public class arraytesting {
public static void main(String[] args) {
Scanner myKeyboard = new Scanner(System.in);
int user_Choice;
int rowAndcolumns;
char[][] user_Array;
char user_Char;
do {
System.out.print("Enter your choice (1 to 9): ");
user_Choice = myKeyboard.nextInt();
if (user_Choice < 1 || user_Choice > 9)
System.out.println("Illegal choice, please try again.");
} while (user_Choice < 1 || user_Choice > 9);
switch (user_Choice) {
case 1:
do {
System.out.print("\nHow many rows and columns (min 4 & max 20)? ");
rowAndcolumns = myKeyboard.nextInt();
if (rowAndcolumns < 1 || rowAndcolumns > 9)
System.out.println("Illegal choice, please try again.");
} while (rowAndcolumns < 4 || rowAndcolumns > 20);
do {
System.out.print("Which character do you want to fill your square with? (only one character)");
user_Char = myKeyboard.next().charAt(0);
if () // error message for user if they did not type correctly, Idk what to put in the
System.out.println("Illegal choice, please try again.");// boolean for it to compare
System.out.print(user_Char);
} while (); // using do-while loop to loop back question, if they don't type in correctly, i
// would only like for user to type in only one character
break;
}
}
}
I know I can put both of them in one do-while loop, but I want to focus on getting the boolean to check for user input.
edit: I would only like the user to enter only one single character
ex. '#' or 'a'
whereas "##" or "i am typing something that is not one character" is wrong
inside the spaces of if and while are how I want it to be verified
There is no need to do any check for "only 1 character entered". That makes no sense. You can't predict the future, so you cannot know if a user will enter more characters after 1 character has been entered. You will either just take the first character entered and work with it and ignore any potential additional characters - or you have to wait for more than 1 character, essentially breaking the program for users who do the right thing (enter only one character), just to be able to give them an error message when they finally do the wrong thing (enter another character).
That being said, this code:
user_Char = myKeyboard.next().charAt(0);
will actually wait for several characters to be entered until some kind of delimiter (per default some whitespace character, e.g. newline) is entered. That's exactly what you do not want.
You want to get one character from input, and one only. You don't have to care about more characters being entered after that:
user_Char = myKeyboard.next(".").charAt(0);
This tells myKeyboard to return the next String that matches the regex ".", which is any character, and only 1 character.
If you want to validate the entered character, e.g. only alphanumeric characters allowed, you can update your if and while to something like this:
if (!Pattern.matches("[a-zA-Z0-9]", new String(user_Char)))
or even better, use the String returned by myKeyboard.next("."):
String user_String = myKeyboard.next(".");
user_Char = user_String.charAt(0);
if (!Pattern.matches("[a-zA-Z0-9]", user_String))
or you could directly tell myKeyboard to only allow valid characters and skip the entire do/if/while error handling:
user_Char = myKeyboard.next("[a-zA-Z0-9]").charAt(0);
Edit
One thing your code doesn't handle right now is invalid inputs, e.g. letters when you call nextInt. This will actually throw a java.util.InputMismatchException, and you might want to wrap your nextInt() and next(...) calls in try-catch blocks to handle these exceptions.
Please check the code below, based on the discussion with Max, I used the .length() method to check the lenght of the string that the user typed.
You can check the type of the character to avoid the runtime exception in the first if statement using some methods in Character class that you use to check if the input is digit/letter or not ?
Character.isDigit(char)
Character.isLetter(char)
Character.isLetterOrDigit(char)
I also changed some variable names, Java is following the camel case style and class name has to be capitalized. I also refactored some code to check the range of the numbers to git rid of repeating same code on and on, check the method betweenExclusive
package stackoverflow.q2;
import java.util.Scanner;
public class Question2 {
public static void main(String[] args) {
Scanner myKeyboard = new Scanner(System.in);
int userChoice;
int rowAndcolumns;
char[][] user_Array;
char userChar;
do {
System.out.print("Enter your choice (1 to 9): ");
userChoice = myKeyboard.nextInt();
if ( !betweenExclusive(userChoice, 1,9) )
System.out.println("Illegal choice, please try again.");
} while (!betweenExclusive(userChoice, 1,9));
switch (userChoice) {
case 1:
do {
System.out.print("\nHow many rows and columns (min 4 & max 20)? ");
rowAndcolumns = myKeyboard.nextInt();
if (!betweenExclusive(rowAndcolumns ,1 , 9))
System.out.println("Illegal choice, please try again.");
} while (!betweenExclusive(rowAndcolumns ,4 , 20));
String input;
while (true){
System.out.print("Which character do you want to fill your square with? (only one character)");
input = myKeyboard.next();
// error message for user if they did not type correctly, Idk what to put in the
// boolean for it to compare
if ( input.length()>1){
System.out.print("Illegal character, try again please !!! ");
}else{
userChar = input.charAt(0);
System.out.print(userChar);
break;
}
} // using do-while loop to loop back question, if they don't type in correctly, i
// would only like for user to type in only one character
break;
}
}
public static boolean betweenExclusive(int x, int min, int max)
{
return x>=min && x<=max;
}
}
This question already has answers here:
Unexpected result in simple java program
(4 answers)
Closed 7 years ago.
I'm working through a piece of code from the "Java: A Beginner's Guide 6th Ed." The section I'm on is explaining the different ways to implement a For Loop.
// Loop until an S is typed.
System.out.println("Press S to stop.");
for(int i = 0; (char) System.in.read() != 'S'; i++)
System.out.println("Pass #" + i);
My question is this - why does it execute 3 times before asking for a new keyboard input? When I type any character, it outputs:
Press S to stop.
T
Pass #0
Pass #1
Pass #2
P
Pass #3
Pass #4
Pass #5
I would expect it to run once and then wait for the next input.
I'm sure you didn't just press 'T' and 'P'.
You pressed 'T' return 'P' return.
And a return on the Windows platform is represented by two characters: carriage return (\r) followed by a line feed (\n).
So by typing 'T' return you typed 3 characters:
'T'
\r
\n
That's why.
It's not a Java thing. Exactly the same thing would have happened if you had written your program in C or Perl.
If you are just using System.in, then it's not possible to get individual keypresses on most consoles - instead you won't get any data until the return has been pressed. You can write a GUI application instead of you want to have more detailed insight into key presses.
As has been mentioned, the extra iterations represent the EOL or End of Line characters. When you type a character as input, you need to type an additional character to deliver the standard input for your program: probably the Enter key.
To see this more clearly, here's a simple amendment to your code:
// Loop until an S is typed.
System.out.println("Press S to stop.");
char read;
for (int i = 0; (read = (char) System.in.read()) != 'S'; i++)
{
System.out.print("Pass #" + i);
// specific checks for LF \n, or CR \r
if (read == '\n')
System.out.println("; char read was: \\n");
else if (read == '\r')
System.out.println("; char read was: \\r");
else System.out.println("; char read was: " + read);
}
Output:
Press S to stop.
T
Pass #0; char read was: T
Pass #1; char read was: \r
Pass #2; char read was: \n
P
Pass #3; char read was: P
Pass #4; char read was: \r
Pass #5; char read was: \n
S
From my output, and from yours, we can make a good guess that the system that we're running this loop on is a Wndows-based system. Note that different operating systems have represented this character differently: so you should expect to see different output when you run your code on a UN*X based system, like on a mac. See the wikipedia article for Newline for more information.
The java language makes a useful abstraction for this that you can use in more complex code: the standard library captures the operating-system dependent value for EOL in System.lineSeparator, see the docs for lineSeparator here
If you wanted to make it work as you were expecting, you could use a scanner like so:
Scanner scanner = new Scanner(System.in);
System.out.println("Press S to stop.");
for(int i = 0; scanner.next().charAt(0) != 'S'; i++)
System.out.println("Pass #" + i);
That gives the following output:
Press S to stop.
W
Pass #0
R
Pass #1
T
Pass #2
S
can you help me on this?
I have this code which is a part of my program :
Scanner a5 = new Scanner(System.in);
while(a5.hasNextLine()) //store every line in mail message until user type "." on a seperate line
{
String text = a5.nextLine();
if (text.charAt(0) != '.')
{txt.add(text);}
else if(text.charAt(0) == '.' )
{break;}
}
I want user to type a message and until he doesn't type "." in a separate line he can add more lines. but my problem is when I press enter I get this error:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String ind
ex out of range: 0
at java.lang.String.charAt(Unknown Source)
at MyPMC.main(MyPMC.java:51)
how can I fix it so it also add empty line to my string?
example:
when I type this in message it work ok :
Hi
my name is jack
.
but when I press enter after second sentence I get error and my program crash, I can't type like this:
Hi
My name is jack
this is message
.
thank you
When you type only enter the Scanner returns an empty String. When you try to get an empty String's first character with text.charAt(0), you go out of range and the StringIndexOutOfBoundsException is thrown.
A quick fix would be to check the length of the String before using charAt as follows:
if (text.length() > 0 && text.charAt(0) != '.')
The problem is that for an empty string, there is no 0th character, so text.charAt(0) fails.
Instead, you can use text.startsWith(".") to test for the first character (or first few characters), and text.isEmpty() to test for an empty input, i.e., when the user hits enter without writing any text first.
Also, since your second if condition is exactly the negation of the first, you can just use else here.
Add simple length check and continue if 0