[NOTE] Add to the answer below for other good tips for reading the stack trace
I am getting an error in a program that I am making and I don't know how to fix it.
The user has to choose options from messageboxes, and I have to use the users input to calculate the tuition they will have and their discount.
If I run it!
run: Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:468)
at java.lang.Integer.parseInt(Integer.java:497)
at cabrera.Main.main(Main.java:26)
Java Result: 1
BUILD SUCCESSFUL (total time: 6 seconds)
Code
package cabrera;
/**
*
* #author Owner
*/
import javax.swing.JOptionPane;
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
String tuition1 = "", scholar1 = "";
int tuition = 0, scholar = 0;
double discount = 0.0;
JOptionPane.showInputDialog("Input Your Tuition" + tuition1);
JOptionPane.showInputDialog("Choose A Scholar Discount:" + "\n• 1 = 80% " + "\n• 2 = 50%" + "\n• 3 = 25%" + "\n• 4 = No Discount !" + scholar1);
tuition = Integer.parseInt(tuition1);
scholar = Integer.parseInt(scholar1);
JOptionPane.showMessageDialog(null, "Your Total Tuition is: " + tuition);
// If-elseif-else statements based on scholar variable
}
}
How do I fix this error message?
More Info
I recently came across a question that was badly executed. Bad title, bad code, bad question (actually not question, but it could be assumed after some thought). It was from a new SO user.
I wanted to help out and looked at the code for a while. So I edited the post; fixed the code layout, simplified the code, ask the question the OP wanted to ask, etc.... That question is now above; however, the question was put on hold, and I read that questions can take a long time to get off of On Hold. You need something like 5 votes to reopen after it is put on hold. Something I don't see that will happen given that it has been a while since the question was first asked.
I had the answer complete and don't want to waste a good answer
OK, lets look at how to find the issue first!
(3) run: Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:468)
(2) at java.lang.Integer.parseInt(Integer.java:497)
(1) at cabrera.Main.main(Main.java:26)
Java Result: 1
BUILD SUCCESSFUL (total time: 6 seconds)
Look at...
(1), here you can see in Main.java you have an issue on line 26
(2), here you can see more information on the issue. In fact you know you have an issue with Integer.parseInt.
You Don't have to worry about looking at this code, because you don't have a class called Integer with method parseInt in the package java.lang
You just know there is an issue here, and it deals with Integer.parseInt which you do call in your Main.java code!
So we located a possible area to check for the error!
tuition = Integer.parseInt(tuition1);
scholar = Integer.parseInt(scholar1);
(3), here we can see that a NumberFormatException was throw because you gave it (the Integer.parseInt that is) an input of "" (an empty string)
So How do you fix it?
First, you have to look at the input of Integer.parseInt
You can see you pass in tuition1 and scholar1
Look to see where those 2 variable are changed / created.
You can see the last thing you did was create those two variables and assigned them the empty string ("")
There is the problem!!
So you need to assign them a value from the user. That will be done via the showInputDialog(...).
the showInputDialog(...) returns a value that you can use! See here!
All you have to do is...
tuition1 = JOptionPane.showInputDialog("Input Your Tuition");
scholar1 = JOptionPane.showInputDialog("Choose A Scholar Discount: 1... 2... 3... 4...")
Take note that tuition1 and scholar1 should NOT be placed inside of the dialog box when you want to assign them values from the user. You need to have the user input some text into the dialog box, and that value will be returned when you press the OK button. So you have to assign that return value to tuition1 and scholar1
You are getting this exception because user is free to enter an input which is not a number. Integer.parseInt(String s) will throw a NumberFormatException if the argument passed to this method is not a valid number. You can restrict the user to input only numbers by the use of regular expressions. The code is below:
String tuition1="";
int tuition = 0;
boolean numFound =false;
try{
while(!numFound){
tuition1 = JOptionPane.showInputDialog("Input Your Tuition:");
Pattern p = Pattern.compile("[A-Z,a-z,&%$##!()*^]");
Matcher m = p.matcher(tuition1);
if (m.find()) {
JOptionPane.showMessageDialog(null, "Please enter only numbers");
}
else{
tuition = Integer.parseInt(tuition1);
numFound = true;
}
}
}
catch (Exception e) {
e.printStackTrace();
}
This will show a message to user "Please enter only numbers", if he tries to enter something that cannot be converted to integer.
Related
I was trying to run my code with a scanner and suddenly it errors when it goes to the 2nd question.
import java.util.Scanner;
public class MyClass {
public static void main(String args[]) {
Scanner stats = new Scanner(System.in);
double base,current;
float bonus;
int level;
System.out.print("Enter the base attack speed: ");
base = stats.nextDouble();
System.out.printf("Enter the bonus attack speed %: " + "%.2f");
bonus = stats.nextFloat();
System.out.println("Enter the level: ");
level = stats.nextInt();
current = (base*1+bonus*level-1) /100;
System.out.print("The character's current speed is: " + current);
}
}
% is what printf (and String.format) use for identifying a placeholder which will be filled in by a parameter provided as second argument.
You therefore have 2 bugs in this code:
The % in attack speed %: is being identified by printf as a placeholder, but you want to print an actual percent symbol. To print that, write 2 percent symbols, which is 'printf-ese' for a single percent symbol: "Enter the bonus attack speed%%: ".
You then add "%.2f" to it which is bizarre, what do you think that does? As written, if you fix the bug as per #1, you immediately get another exception because this requires an argument. The idea is that you can do something like: System.out.printf("The speed of the vehicle in km/h is: %.2f", someValue);. If someValue is, say, 39.8993, that will print the string "The speed of the vehicle in km/h is: 39.90", because you asked for: Print a value as floating point value with max 2 fractional digits. You don't have any input to print there - you're still asking the user, and you can't use this kind of thing to 'format' what the user is supposed to put in. That comes later. So presumably you want to just get rid of that entire "%.2f" thing there.
I am currently working on Java code. Basically, the int input works. However, if I type in a character, the whole system crashes. My question is as to what needs to be changed in the below code in order for the user to receive a message stating that only an int is the valid input, and to try again if they input a character.
do {
System.out.println("How many players would like to participate in this game?\t(2-4 players)");
numberOfPlayers = in.nextInt();
} while(in.hasNextInt());
numberOfPlayers = in.nextInt();
I personally prefer to use a while loop for this sort of thing rather than the do/while. Not that there is anything wrong with the do/while, I just feel it's more readable to use the while loop.
I agree with others here, accept String digits from the User instead of Integer. In my opinion it saves you other possible problems down the road and you have no need to purposely apply a try/catch mechanism should the User supply an invalid entry. It also allows you to easily apply a mechanism to quit the application which, again IMHO, should be made available to all Console app's.
You've got your answer for carrying out the task using a do/while loop but I would like to show you another way to do this sort of thing:
Scanner in = new Scanner(System.in);
String ls = System.lineSeparator();
int numberOfPlayers = 0;
String userInput = "";
while (userInput.equals("")) {
// The Prompt to User...
System.out.print("How many players would like to participate in this game?" + ls
+ "2 to 4 players only (q to quit): --> ");
userInput = in.nextLine();
// Did the User enter: q, quit (regardless of letter case)
if (userInput.toLowerCase().charAt(0) == 'q') {
// No, the User didn't...
System.out.println(ls + "Quiting Game - Bye Bye.");
System.exit(0); // Close (exit) the application.
}
/* Did the User supply a string representation of a numerical
digit consiting of either 2, 3, or 4. */
if (!userInput.matches("[234]")) {
// No, the User didn't...
System.out.println("Invalid input! You must supply a number from 2 to 4 "
+ "(inclusive)." + ls + "Try again..." + ls);
userInput = "";
continue; // Loop again.
}
// Convert numerical string digit to an Ingeger value.
numberOfPlayers = Integer.parseInt(userInput);
}
System.out.println(ls + "The Number of players you provided is: --> "
+ numberOfPlayers);
You will notice that the Scanner#nextLine() method is used to accept User input as a String. This now means that we need to validate the fact that a string representation of a Integer numerical digit (2 to 4 inclusive) was supplied by that User. To do this you will notice that I used the String#matches() method along with a small Regular Expression (RegEx) which consists of the following string: "[234]". What this does in conjunction with the String#matches() method is it checks to see if the string value in the userInput variable contains either a single "2", a single "3", or a single "4". Anything else other than any one of those three digits will display this message:
Invalid input! You must supply a number from 2 to 4 (inclusive).
Try again...
and, force the User make yet another entry.
I try to custom my Java Console Application, but I have a problem when I try to show it in Command Prompt will appear input Scanner between String...
int a;
Scanner scan = new Scanner(System.in);
System.out.println("Input value of a: " + (a = scan.nextInt()) + " !");
Anyone can resolve this problem, help me....
thank you
1. First of all, your code runs as it is coded not as it is expected.
As your output is blank, and you are wandering why the prompt has not come yet for asking the user input, then let me tell you one thing, that it is actually asking you to enter some input right there. As soon as, you will enter, you shall see the next line of your output will be..
Input value of a: (whatEverYouEntered)
So your final output would be, (strictly as per your code..)
F:/SMK/oop>javac Main.java
F:/SMK/oop>5 (assumed you type 5 and press enter)
F:/SMK/oop>Input value of a: 5
2. If you think that your code should print Input value of a: line fist and then you will enter the value, then you'll have to make changes as below.
int a;
Scanner scan = new Scanner(System.in);
System.out.print("Input value of a: ");
a = scan.nextInt();
3. And if you are really curious about the reason why your code was behaving like that..then read this..
I would say, change your code as stated below and then run, you might get a hint, otherwise I'll explain later.
public static void main(String[] s) {
int a = 0;
Scanner scan = new Scanner(System.in);
System.out.println("Input value of a: " + (a = new Main().getVal()) + " !");
System.out.println("A = " + a);
}
public int getVal(){
System.out.println("getVal called first.");
return 5;
}
See the output now, it shall be.
F:/SMK/oop>javac Main.java
F:/SMK/oop>getVal called first.
F:/SMK/oop>Input value of a: 5
The reason is, when JVM interprets System.out.println("Input value of a: " + (a = new Main().getVal()) + " !"); this as a single statement, and to execute it must be complete... so how will it get complete?--> By assigning the value of a. and to do so, it must call getVal() function before printing anything, right?
Exactly the same is happening in your code, as your print statement will be executed after the call of scan.nextInt() and nextInt() immediately asks for user input without showing any message in console. And once the input is provided, it will assign the value to a and now the print statement is actually complete and ready to execute. And hence, you would see the print output after the input prompt.
Hope it gives you good idea about java and programming language as well.
Happy coding :)
So I am doing a project for a class of mine and it involves the use of delimiters and other scanner methods. However I've been doing a lot of research and the book we have does not clearly explain as to how it works. So after several headaches and trying to understand I figured I'd ask here (EDIT: This is something somewhat similar I found [relating to delimiters and splitting number sequences] to what my teacher was asking me and thought it would be adequate to ask it here. So before I get accused of doing my homework on here I wanted to clarify)
Here's what I have typed so far:
import java.io.*;
import java.util.*;
public class addUp
{
public static void main(String args[])
{
Scanner kb = new Scanner(System.in);
System.out.print("Enter something like 8 + 33 + 1345 - 137 : ");
String s = kb.nextLine( );
Scanner sc = new Scanner(s);
/* sc.useDelimiter("\\s*"); With some help and research I found
out that the \\s* actually causes every character to be split
apart. so 33 is 3 3 */
int sum = sc.nextInt();
while(sc.hasNextInt( ))
{
String operator = sc.next();
int value = sc.nextInt();
if(operator.equals("-"))
{
sum = sum - value;
}
else if(operator.equals("+"))
{
sum = sum + value;
}
}
System.out.println("Sum is: " + sum);
}
}
And my last attempt got me a weird output:
----jGRASP exec: java addUp
Enter something like 8 + 33 + 1345 - 137 : 8 + 33 + 1345 - 137
Sum is: 8
----jGRASP: operation complete.
Now I don't know a ton and I'm sure if I came in with something more complicated than the progress of what we've been through would not be appreciated (since I know I've seen some people answer other questions that is way over my understanding). So keep it dumbed down for me if you can XD. Thanks.
The problem with your code at the moment is that your while loop is checking for while(sc.hasNextInt( )), but it's expecting an operator. Change that to while(sc.hasNext() and you should be ok.
Additionally, when facing problems like this, try running your code in a debugger and stepping through it. You'd see pretty quickly that it didn't enter into the while loop and that would help you diagnose the problem. If you don't have access to a debugger, just put in some System.out.println() statements.
UPDATE
So, I ran your code in a debugger (after changing the while loop as I described), and the first thing I noticed was that the first call to sc.nextInt() returns 3, not 33, because of the reason H L explained. Having removed the call to setDelimeter, the code runs fine. It should now look like:
import java.io.*;
import java.util.*;
public class addUp
{
public static void main(String args[])
{
Scanner kb = new Scanner(System.in);
System.out.print("Enter something like 8 + 33 + 1345 - 137 : ");
String s = kb.nextLine( );
Scanner sc = new Scanner(s);
//sc.useDelimiter("\\s*"); <-- don't do this
int sum = sc.nextInt();
while(sc.hasNext( )) // <-- not hasNextInt
{
String operator = sc.next();
int value = sc.nextInt();
if(operator.equals("-"))
{
sum = sum - value;
}
else if(operator.equals("+"))
{
sum = sum + value;
}
}
System.out.println("Sum is: " + sum);
}
}
And outputs:
Enter something like 8 + 33 + 1345 - 137 : 8 + 33 + 1345 - 137
Sum is: 1249
Again, you should have spotted this if you stepped through your code in a debugger (Eclipse, IntelliJ, NetBeans, jdb, etc).
There are multiple issues with your code:
You call the next() and nextInt() methods multiple times within the while loop which consumes too much of our input.
The sum is initialized to 0 and the very first operand is omitted.
Only the last else block is executed because you compare strings with characters (single quotes instead of double quotes) which always evaluates to false.
Code:
// WRONG: sc.useDelimiter("\\s*");
int sum = sc.nextInt(); // consume the first token, must be an integer
while (sc.hasNext()) { // as long as there are more tokes, do the following
String operator = sc.next(); // read next token, must be a + or - sign
int operand = sc.nextInt(); // read next token, must be an integer again
// depending on the arithmetic operator we update the sum variable
if (operator.equals("-")) {
sum = sum - operand;
} else if (operator.equals("+")) {
sum = sum + operand;
} else {
// if the operator variable contains something else than a + or - sign
// we throw an exception. In general this is the preferred way to avoid
// that the software changes into an undefined state.
throw new RuntimeException("Unknown operator: " + operator);
}
}
System.out.println("Sum is: " + sum);
First Problem (Apparently corrected in an edit to the quesiton)
You call sc.next() in every if statement. Call it once, and then use the value when you need it. If you keep calling it, you'll keep eating your input!
String op = sc.next();
if (op.equals('-') {}
else if (op.equals('+') {}
else {}
Second Problem
You never initialize sum to the first number. You skip the first number completely! Start off like this to make sure you consume the first int before you consume the first operator.
int sum = sc.nextInt();
Third Problem
hasNextInt() only returns true if the next token is an int. It returns false if the next token is an operator like "+" or "-". Change your while to loop on hasNext().
The last fix may cause you to consume a "/n" or some other line seperator nonsense on your last iteration of the loop. as it stands, it looks like this will only cause you to print the sum twice. That seems like something you should be able to solve on your own.
Rather than making me edit my answer four MORE times, try to do this on paper, going in circles for the while loop. Consume an int. Consume an operator. Consume an int. Consume an operator. Consume an int. If you break that order, your logic isn't in the right order. Know the logic before you even try to write code.
Go read the Javadoc for Scanner to see what each method you are calling actually does. Learn about Streams in Java so you understand how they work.
This program wont run on netBeans or compile in terminal...I dont think i have any erros in the itself..
This program needs to display the area of a circle
there cannot be any invalid input (letters, &^#,..etc)
Please and thank you for your time ;)
**import java.util.Scanner;
/**
*
* #author Omar Sugule
*/
public class AreaCircle {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Scanner sc = new Scanner(System.in); // read the keyboard
try {
double r = sc.nextDouble();
}
catch( NumberFormatException e ) {
System.err.println("Invalid Input, please enter a number");
//put a message or anything you want to tell the user that their input was weird.
}
System.out.println("This program will calculate the area of a circle");
System.out.println("Enter radius:");//Print to screen
double r = sc.nextDouble(); // Read in the double from the keyboard
double area = (3.14 *r * r);
String output = "Radius: " + r + "\n";
output = output + "Area: " + area + "\n";
System.out.println("The area of the circle is " + area);
}
}**
You know that this won't work:
try {
double r = sc.nextDouble();
}
catch( NumberFormatException e ) {
System.err.println("Invalid Input, please enter a number");
//put a message or anything you want to tell the user that their input was weird.
}
since you declare r from within the try block, it is only visible inside the try block and is completely invisible elsewhere (this is called being out of "scope").
Instead:
Declare double r before the try block and initialize it to 0.0:
double r = 0.0; // corrected as per mfrankli
Try to get the input in the try block
enclose all in a while loop and continue looping until the input is valid
don't re-declare r after the try block.
work on improving your code formatting, in particular to get your code indentation uniform. Doing this will make the code a lot easier for you and us to debug.
Work on asking better questions here. It's usually a good idea to give all the information necessary to help you in the initial question. Yours leaves out a lot of stuff making us have to guess which can lead to incorrect or confusing answers.
I've just tried out your program, and the only real problem that I see is that you have this bit at the beginning that waits for user input:
try {
double r = sc.nextDouble();
}
catch( NumberFormatException e ) {
System.err.println("Invalid Input, please enter a number");
//put a message or anything you want to tell the user that their input was weird.
}
Since that code comes before the program produces any output, the effect is of a program that simply hangs; it's not obvious to the user that they should enter a number. (And indeed, they needn't bother worrying too much about the number they enter, since the program just prompts them to enter another number a bit later down:
double r = sc.nextDouble(); // Read in the double from the keyboard
and it's this second one that is actually used.)
Remove the asterisks at the beginning and end of file. The rest is okay, except having to press enter before actually giving any input.