I want to accept user input as either an integer or a string in Java but I always get an error no matter what I do.
My code is very simple (I'm a beginner):
System.out.println(
"Enter the row number (or enter e to quit the application):"
);
Scanner rowInput = new Scanner(System.in);
int row1 = rowInput.nextInt();
I want the user also to be able to press "e" to exit.
I have tried several things:
1) To convert row1 to a String and and say:
if((String)(row1).equals("e"){
System.out.println("You have quit") }
2) To convert "e" to an integer and say:
if(row1 == Integer.ParseInt("e"){
System.out.println("You have quit") }
3) To do the switch statement but it said I had incompatible types (String and an int).
My errors usually say: Exception in thread "main" java.util.InputMismatchException
Is there somebody who could help me?
Many thanks in advance!
You can try something like this
Scanner rowInput = new Scanner(System.in);
String inputStr = rowInput.nextLine();
try{
int row1 = Integer.parseInt(inputStr);
} catch (NumberFormatException e) //If exception occurred it means user has entered 'e'
{
if ("e".equals(inputStr)){
System.out.println("quiting application");
}
}
you should read the input from your scanner as String type and the try to convert that String input into integer using Integer.parseInt().
If its successful in parsing, it means user has input an Integer.
And If it fails, it will throw an exception NumberFormatException which will tell you that its not an Integer. So you can go ahead and check it for e if it is, do whatever you want as per your requirement.
You can't use nextInt() if you aren't sure that you will have a number coming in. Also, you can't parse e as an integer, because it is not an integer, it's either char or string (I'll suggest string in this case).
That means, your code should look like:
System.out.println("Enter the row number (or enter e to quit the application):");
Scanner rowInput = new Scanner(System.in);
string row1 = rowInput.next();
Then you have the data in a string. You can simply check if the string is e:
if (row1.Equals("e")) ...
It is also a good idea to check if the input is actually an integer then. Good way to check it is described here:
How to check if a String is numeric in Java
1) you should say Integer.parseInt() instead of Integer.ParseInt()
2) if you pass "e" to Integer.parseInt() you'll get java.lang.NumberFormatException
3) get your input as a string this way (cause it's safer)*:
Scanner rowInput = new Scanner(System.in);
String row = rowInput.next();
if (row.equals("e")) {
//do whatever
}
else if(row.matches("\\d+$")) {
//do whatever
}
*In your approach if user enters a non-integer input you'll encounter java.util.InputMismatchException
I have tried several things ....
Attempting to solve this problem by "trying things" is the wrong approach.
The correct approach is to understand what is going on, and then modify your solution to take this into account.
The problem you have is that you have a line of input that could be either a number or the special value e which means quit. (And in fact, it could be a couple of other things too ... but I will come to that.)
When you attempt to either:
call Scanner.nextInt() when the next input is not an integer, OR
call Integer.parseInt(...) on a String that is not an integer
you will get an exception. So what do you do?
One way is to change what you are doing so that you don't make those calls in those situations. For example:
call Scanner.hasInt() to see if the next token is an integer before calling nextInt(), or
test for the "e" case before you attempt to convert the String to an integer.
Another way to deal with this is to catch the exception. For example, you could do something like this:
String s = ...
try {
number = Integer.parseInt(s);
} catch (NumberFormatException ex) {
if (s.equals("e")) {
...
}
}
Either way will work, but I'm going to leave you to work out the details.
But the real point I'm trying to make is that the right way to solve this is to understand what is happening in your original version / versions, and based on your understanding, modify what you were doing. If you just randomly "try" alternatives that you found with Google, you won't progress to the point of being a productive programmer.
I said there were other cases. They are:
The user types something that is neither a number of your special e character. It could be anything. An empty line, hi mum ...
The user types the "end of file" character; e.g. CTRL-D on Linux or CTRL-Z on windows.
If you want your program to be robust you need to deal with these cases too.
Try this:
public class Demo{
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
String choice = null;
System.out.println("Enter e to exit or some other key to stay:");
choice=s.next();
if(choice.equals("e"))
{
System.out.println("quits");
System.exit(0);
}
else
{
System.out.println("stays");
}
}
}
You can't convert a string into integer, use char ASCII codes instead.
Related
I am loath to reinvent this bicycle and am hoping to be shown the tried and true way to handle this problem.
I'm collecting numeric values from users via some String interface (text input for instance).
I want to make sure that regardless of what type of memory space I'm using for collecting this info, I don't allow the user to enter a number that exceeds this value.
My intuition tells me that the only way to do this is to actually measure the string length of the max value... such as...
if( (userInput + "").length() > (Integer.MAX_VALUE + "").length()){
//user has entered too many digits for an Integer to hold.
}
But this looks ugly to me and I'm guessing there's a cleaner way to handle this.
When you get the userInput for the first time you should verify that what the user enters is valid and if it is, then Integer.parseInt() will work. If it's not valid, i.e. a value greater than Integer.MAX_VALUE, it will throw an exception.
The behavior you're describing leads to using the catch as flow control which is not a good design...
BAD:
try{
Integer.parseInt(max);
//do something with the integer
}catch (NumberFormatException e)
{
//user has entered too many digits for an Integer to hold.
userInput = Integer.MAX_VALUE + "";
}
The constructor of Integer would detect that for you, by throwing a NumberFormatException if the user input is either out of range or not really an integer. See the following test program example:
public class UserInputBigInteger {
public static void main(String[] args) {
String[] inputStrings = {
String.valueOf(Integer.MAX_VALUE)
, String.valueOf(Integer.MAX_VALUE)+"0" // x10
, String.valueOf(Integer.MAX_VALUE)+"a" // not an integer
};
for (String inputString : inputStrings) {
try {
Integer inputInteger = new Integer(inputString);
final int MAX = Integer.MAX_VALUE;
System.out.format("userInput %s is within range %,d%n"
, inputString, MAX);
} catch (NumberFormatException ex) {
System.out.format("userInput does not appear to be valid interger: %s%n"
, ex.getMessage()); }
}
}
}
The output would be:
userInput 2147483647 is within range 2,147,483,647
userInput does not appear to be an interger: For input string: "21474836470"
userInput does not appear to be an interger: For input string: "2147483647a"
You could also try this to get the bit information:
BigInteger userInputCheck=new BigInteger(userInput);
if(userInputCheck.bitLength()>31){
//error : cannot convert the input to primitive int type
}
EDIT
If you are using Apache Commons there is a method createNumber# in the NumberUtils utility class.
From the documentation:
...it starts trying to create successively larger types from the type specified
until one is found that can represent the value...
Source Code for the above method
I am programing in java and have also very little programming experience.
I am trying to make a program there you first write in a number of integers in a scanner. In the next window you are supposed to write only one integer and that integer the program will search for and tell if it is or isn't in the "Scanner numbers"
My problem is that when i for example write 1 2 3 and in the next window write 2 it doesn't recognize there is a 2 in the scanner but if I instead write a 1 it works nicely.
Heres the code:
public class Inlämningsuppgift_kap9 {
public static void main(String[] args) {
String s1 = JOptionPane.showInputDialog("Write any number of integers!");
Scanner sc1 = new Scanner(s1);
String s2 = JOptionPane.showInputDialog(
"Chose a integer that the program will search for!"
);
int a = Integer.parseInt(s2);
while(sc1.hasNextInt()){
if(a == sc1.nextInt()){
JOptionPane.showMessageDialog(null, "The integer can be found");
System.exit(0);
}
else {
JOptionPane.showMessageDialog(null, "The integer cannot be found");
System.exit(0);
}
}
}
}
Thanks for any help!
Not going to do your homework for you, but a hint there: it is not a good idea to mix Swing UIs and a scanner that reads from stdin.
In other words: either use a graphical UI for all input/output; or just read/write from/to stdin (using out.println and that scanner code).
And then: assuming that the user first enters a string such as "1 2 3 4 5"; you need some further processing. You have to split that string (for example on spaces); and then turn each of that substrings ... into a real number. As your next step is to ask the user to input a number. And when you want to know if one number is in a list of other numbers, then you need to turn your initial string into that list of numbers!
So, you want to study javadoc for:
String.split()
Integer.parseInt()
you should not parse the input. makes it much easier to do what you want.
String s1 = JOptionPane.showInputDialog("Write any number of integers!");
String s2 = JOptionPane.showInputDialog("Chose a integer that the program will search for!");
for(int i=0;i<s1.length();i++){
if(s1.charAt(i)==s2.charAt(0)){
JOptionPane.showMessageDialog(null, "The integer can be found");
System.exit(0);
}
}
JOptionPane.showMessageDialog(null, "The integer cannot be found");
System.exit(0);
i like this solution more since it has less code an still works fine
lets just anylyze your code and hope i'm not mistaken :) , the variables are initialized,then You start a loop with
while(sc1.hasNextInt())
it basically runs for x times where x is the number of inputs (sc1 variable's length) then you test if the number in current iteration is the number you look for. If it's you print success code and close the loop. if it isn't you print failure code and also close the loop. So when you provide 1 as input the execution is fine because 1 is the 1st element but 2 as second argument is never tested because of
System.exit(0);
in else's brackets
First post so my apologies if this was done incorrectly (and am also relatively new to programming, so any extraneous tips are also appreciated).
So I have written up a basic calculator program in Java. It works well currently, but I am having a particular issue with NumberFormatException. Here's the code:
private static double spaceTestAndConvert(String numInput){
Scanner input= new Scanner(System.in);
if (numInput.equalsIgnoreCase("quit")){
System.exit(1);
}
else if(numInput.equalsIgnoreCase("C/E")){
Restart();
}
try{
return Double.parseDouble(numInput.trim());
}
catch(NumberFormatException nfe){
numInput = "";
System.out.println("Please enter only one number without any spaces or letters: ");
numInput = input.nextLine();
spaceTestAndConvert(numInput.trim());
return Double.parseDouble(numInput.trim());
}
}
The issue is that after trying to force an error by entering in several inputs which would cause NumberFormatException and then entering in a valid input, the program will crash from a NumberFormatException citing the previous invalid input.
I.E. -
"1 2 3"
loops back
"1 2 q 3"
loops back
"12q3 3 sqw 1"
loops back
"12"
crash - Exception in thread "main" java.lang.NumberFormatException: For input string: "12q3 3 sqw 1"
It only occurs after several occurrences of the exception. I'm curious why it is doing this. Any advice on how to fix this or explanation of what is happening? If you need any other part of the code, please let me know! Thanks!
I don't follow everything that you're saying, but these 2 lines (from within your catch block) look problematic...
spaceTestAndConvert(numInput.trim());
return Double.parseDouble(numInput.trim());
You are calling the spaceTestAndConvert function recursively, but throwing away the value. I don't understand why you would call it and not be interested in the value.
The second line is also a mess. You so carefully surround the first call to Double.parseDouble() with try/catch, but then you call it again within your catch block. If the second Double.parseDouble() generates a NumberFormatException, it will not be caught.
removing the return in catch will solve your problem. because if you have return on it, you are going to return an invalid Number format since you are in a catch. What you want to do is to return a value when it is now valid, you are now actually doing it inside the try. Don't force your program to return the value with error (since it is in a catch) because it will really give you an error.
returning to previous method after you had the right value (because of recursion) will still have the stack of error value aside from success value you gained from the end part because they are different variables.
private static double spaceTestAndConvert(String numInput){
Scanner input= new Scanner(System.in);
if (numInput.equalsIgnoreCase("quit")){
System.exit(1);
}
else if(numInput.equalsIgnoreCase("C/E")){
Restart();
}
try{
return Double.parseDouble(numInput.trim());
}
catch(NumberFormatException nfe){
numInput = "";
System.out.println("Please enter only one number without any spaces or letters: ");
numInput = input.nextLine();
spaceTestAndConvert(numInput.trim());
}
}
New programmer here. This is probably a really basic question, but it's stumping me nevertheless.
What I'm trying to do is write a method that supplies only one integer input so I can use that input in my main program without having to mess around with non-integer inputs. However, even writing the method to do that in its own method seems to be problematic.
public static int goodInput () {
Scanner input = new Scanner (System.in); //construct scanner
boolean test = input.hasNextInt(); //set a sentinel value
while (test == false) { //enter a loop until I actually get an integer
System.out.println("Integers only please"); //tell user to give me an integer
test = input.hasNextInt(); //get new input, see if it's an integer
}
int finalInput = input.nextInt(); //once i have an integer, set it to a variable
input.close(); //closing scanner
return finalInput; //return my integer so I don't have to mess around with hasNextInt over there
}
This seems to be broken in multiple levels, but I'm not really sure why.
If I enter an integer value like 0 or 1 when I'm first asked for input, it should skip the loop entirely. But, instead, it enters the loop, and prints "Integers only please". Even worse, it doesn't actually ask for input while I'm in there, and just prints that line repeatedly.
I understand the latter problem is probably due to token issues, but I'm not necessarily sure how to solve them; closing and then reopening the scanner gets Eclipse to bug me over "duplicate objects", simply assigning the old input to a garbage String variable that is never used tells me that "No line was found" at runtime, and I'm not experienced enough to think of other ways to get new input.
Even once that's solved, I need to find some way to avoid entering the loop in the case of having an integer. I don't really understand why integer inputs inter the loop to begin with, so I'm not sure how this would be possible.
Please help? Sorry if this is an old question; tried looking at past questions but none of them seem to have the same problem that I have.
You were close: this works fine for me:
Scanner input = new Scanner(System.in); //construct scanner
while(!input.hasNextInt()) {
input.next(); // next input is not an int, so consume it and move on
}
int finalInput = input.nextInt();
input.close(); //closing scanner
System.out.println("finalInput: " + finalInput);
By calling input.next() in your while loop, you consume the non-integer content and try again, and again, until the next input is an int.
//while (test == false) { // Line #1
while (!test) { /* Better notation */ // Line #2
System.out.println("Integers only please"); // Line #3
test = input.hasNextInt(); // Line #4
} // Line #5
The problem is that in line #4 above, input.hasNextInt() only tests if an integer is inputted, and does not ask for a new integer. If the user inputs something other than an integer, hasNextInt() returns false and you cannot ask for nextInt(), because then an InputMismatchException is thrown, since the Scanner is still expecting an integer.
You must use next() instead of nextInt():
while (!input.hasNextInt()) {
input.next();
// That will 'consume' the result, but doesn't use it.
}
int result = input.nextInt();
input.close();
return result;
This is an assignment i have to complete.
Can someone lead me in the right direction?
The program compiles but wont run correctly.
The error is InputMissmatch exception.
The error you are getting means that you are trying to use some kind of data as another one, in your case, you are probably trying to use a String as a float.
When using any of the next methods in the Scanner class you should first be sure that there's an appropiate input from the user.
In order to do so, you need to use the has methods.
Your problem is that you are not checking wether the input is a correct float or not before using your Scanner.nextFloat();
You should do something like this:
if (hope.hasNextFloat())
{
// Code to execute when you have a proper float,
// which you can retrieve with hope.nextFloat()
}
else
{
// Code to execute when the user input is not a float
// Here you should treat it properly, maybe asking for new input
}
That should be enough to point you in the right direction.
Also, check the Scanner api documentation for further details.
EDIT
Also, you are asking the user to input characters (or strings): "A", "B", etc..., but you are trying to compare them with a float. That's wrong, you should compare them with a string or character, like this:
if (hope.hasNextString())
{
if (hope.nextString().equals("A"))
{
// Code for option "A"
}
else if (hope.nextString().equals("B"))
{
// Code for option "B"
}
else ...
}
You could use a switch there, but it seems that you are not yet very fammiliar with java, so I'll leave it for another time.
Your problem is that you are entering a letter into a float field.
In your program you're asking the user to enter a float:
A = hope.nextFloat();
But if you enter the letter "A", you're going to get an exception because "A" is not a float, it's a string.
A simpler way to solve your problem is instead of having all the choices fields, you just read the input the user enters from the scanner like:
String choice = hope.next();
Next in the if statement, you check if the value from the string choice is equal to a specific letter, for example
if (choice.equals("A")) {
number4 = (number1 + number2 + number3);
System.out.printf("Your results are:" + (number4));
}
And you can do the same thing for the other choices you have.