I am a newbie with Java and I'm making a very simple Java program like this:
package exercise7;
import java.util.Scanner;
public class Exercise7 {
public static void main(String[] args) {
// TODO code application logic here
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter a number between 0.0 and 1.0.");
keyboard.nextDouble();
}
}
My problem is, when I enter 0.1 for example, they said to me that I had this problem:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextDouble(Scanner.java:2413)
at exercise7.Exercise7.main(Exercise7.java:30)C:\Users\Anh Bui\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1BUILD FAILED (total time: 7 seconds)
I am very confusing, because I thought that nextDouble could mean 0.1 or something like that? Could you please help me? Thank you very much.
The reason between this is just between using 1.1 or 1,1 in different zones.
The way the Scanner reads the nextDouble is related to your Locale or Zone setting (which, if not overrided, are loaded from system).
For example, I'm in Poland and my delimiter for decimal or floating point numbers is , and regardless the Java standard syntax is to use dot(.), if I input some number with . I'll also get InputMismatchException, but when I use ,, e.g. 0,6 it finishes flawlessly.
In the same time, regardless of the Zone or Locale, the valueOf or parseDouble methods from Double class are using . as floating point separator.
Scanner class methods starting with next... are based on the built-in patterns for discovering the proper values. The discovery pattern is build with the common/regular way of writing numbers/values (of the specified type) in your country/zone.
This is very similar to the Data types, which differs even more on their zone of use.
One of the ways of handling InputMismatchException here is to catch this exception and require the user to provide the number again, similarly to this question.
Your case is a bit different from the input of natural number (because 1.1 and 1,1 should indicate the floating point number.
The simplest way of handling those two separators for decimal numbers would be to read the input as String, replace the wrong separator and parse to double, like:
static double getDouble(String doubleS) {
doubleS = doubleS.replace(',', '.');
try {
return Double.parseDouble(doubleS);
} catch (NumberFormatException e) {
e.printStackTrace();
throw e;
}
}
Thanks to #Andreas comment, the most appropiate way of handling this would to require the user to provide a decimal number with . separator, because the printed message (before input) has the separator in its numbers.
This could be done with setting the type of Scanner object locale before number input like:
Scanner keyboard = new Scanner(System.in);
keyboard.useLocale(Locale.US); //this sets the locale which has below separator
System.out.println("Enter a number between 0.0 and 1.0.");
Related
I've only just started learning programming in Java and I cannot figure out how to store a value from user input as a double.
Here's my code:
package FirstProject;
import java.util.Scanner;
public class TripPlanner {
public static void main () {
Scanner console = new Scanner(System.in);
System.out.print("How many " + currencySymbol + " are there in 1 USD? ");
double conversion = console.nextDouble();
}
}
I don't understand why when I enter, for example 19.5, it gives me exception error. My understanding is that I defined the conversion variable as double (double conversion) and I expect the user to enter a double (console.nextDouble();). It's fundamental but coming from Python I can't understand what I'm doing wrong.
Using the Scanner like you did is somewhat uncontrolled. For example, the format the scanner expects is locale-dependent. If your system settings are German, for example, then you need to enter 3,7 for a double value of 3.7.
If the format of the entered string is invalid, then an exception will be thrown, probably java.util.InputMismatchException. You should catch the exception and react in a way that's fit to you use case.
To get better control over the locale used, you should instead read a string from the console and then for example use a java.text.NumberFormat.
See this question.
#Leisetreter pointed me in the right direction. It was the keyboard settings. I live in the UK and use the conventions of writing a decimal number with a dot. However, my keyboard was set to Polish programmer's. In Poland decimal numbers are written with a ",". Once I changed the settings I did not have that problem anymore. It would have never occurred to me. Thanks #Leisetreter.
I don't see any mistake in your code. Except from main.
The proper way you should call her is public static void main (String args[])
I have a question regarding the behavior of the NumberFormat:
When I want to translate/parse a formatted String into a Number, then I would like to use NumberFormat, since it provides me with nice presets for thousand and decimal separators. Additionally I would like it to crash, if the provided String is not a valid Number.
An example:
// works as expected
String testInput1 = "3,1415";
NumberFormat germanNumberFormat = NumberFormat.getInstance(Locale.GERMANY);
Number number1 = germanNumberFormat.parse(testInput1);
System.out.println(number1); // prints 3.1415
// does not work as expected, cuts off the number after the 2nd decimal
// separator, expected it to crash with java.lang.NumberFormatException:
// multiple points
String testInput2 = "3,14,15";
Number number2 = germanNumberFormat.parse(testInput2);
System.out.println(number2); // prints 3.14
I currently use Double.parseDouble(String s), to have this additional behavior:
// crashes with java.lang.NumberFormatException: multiple points
double number2WithError = Double.parseDouble(testInput2.replace(",", "."));
Is there a way I can use NumberFormat to have my required/expected behavior besides writing my own wrapper class that does some additional checks on e.g. multiple decimal separators?
Also I'm aware that the JavaDoc of the used parse(String source) method of NumberFormat says:
Parses text from the beginning of the given string to produce a number. The method may not use the entire text of the given string.
See the {#link #parse(String, ParsePosition)} method for more information on number parsing.
and parse(String source, ParsePosition parsePosition):
Returns a Long if possible (e.g., within the range [Long.MIN_VALUE, Long.MAX_VALUE] and with no decimals), otherwise a Double. If IntegerOnly is set, will stop at a decimal point (or equivalent; e.g., for rational numbers "1 2/3", will stop after the 1). Does not throw an exception; if no object can be parsed, index is unchanged!
This doesn't tell me though why the method behaves this way. What I get from these is that they can parse only parts of the String (what they obviously do here) and probably just start parsing at the beginning (start position) until they find something they can't deal with.
I didn't find an existing question covering this, so if there is already one, please feel free to close this post and please link to it.
NumberFormat.parse(String) is behaving exactly as documented:
Parses text from the beginning of the given string to produce a number. The method may not use the entire text of the given string.
(Emphasis added)
You ask:
Is there a way I can use NumberFormat to have my required/expected behavior besides writing my own wrapper class that does some additional checks on e.g. multiple decimal separators?
You cannot provide a format that will make NumberFormat.parse() throw an exception for input with only an initial substring that can be parsed according to the format. You can, however, use NumberFormat.parse(String, ParsePosition) to determine whether the whole input was parsed, because the parse position argument is used not only to indicate to the method where to start, but also for the method to say where it stopped. That would be a lot better than implementing format-specific extra checks. Example:
ParsePosition position = new ParsePosition(0);
Number result = format.parse(input, position);
if (position.getIndex() != input.length()) {
throw new MyException();
}
Additionally, you write:
This doesn't tell me though why the method behaves this way.
It behaves that way because sometimes parsing the initial portion of the input is exactly what you want to do. You can build stricter parsing on top of more relaxed parsing, as shown, but it's much more difficult to do it the other way around.
here is my code that isn't working:
Scanner hello = new Scanner (System.in);
double a = 10;
double c;
System.out.print("Enter the value: ");
c = hello.nextDouble();
double f = a + c;
System.out.printf("The sum of 10 plus user entry is : ", a+c);
No syntax error whatsoever, no error displayed, this is the result :
Enter the value: 100
The sum of 10 plus user entry is :
So there is no result in the second line,,, for the command ( a+c ) as in program. But if i use a ' %.2f ' before ( a+c ) command, it works fine,,
like :
System.out.printf("The sum of 10 plus user entry is : %.2f", a+c);
I tried to search about the '%.2f' but got to know it is used just to ascertain that the following number is to be displayed as a number with two decimal places. (kinda round off thing, i guess)..
I'm totally a rookie at Java. Started studying it at college right now. Was just curious to know about this concept and reason behind why this program worked only with the '%.2f' typed in it, and not without it, although it showed no error. Will be great if someone can answer it. thanks :-)
Java's System.out.printf() method doesn't append information; it substitutes it. The '%.2f' means: "Replace this with the next argument, and convert it to a floating-point number 2 places precise." Removing the '%.2f' would mean that a+c would have nowhere to go, and printf() would discard it.
Since Java's System.out.printf() method is actually based on the printf() from C/C++, you might want to check out this guide.
You are using the wrong function.
You should be using
System.out.println(myString)
Or
System.out.print(myString)
You would format your code as
System.out.println(myExplinationString + a+c)
System.out is an instance of java.io.PrintStream class that is provided as a static field of the System class. printf(String format, Object... args) is one of the methods of the PrintStream class, check this Oracle tutorial on formatting numbers. In brief, the first argument is a format string that may contain plain text and format specifiers, e.g. %.2f, that are applied to the next argument(s). All format specifiers are explained in the description of the java.util.Formatter class. Note, that double value is autoboxed to Double.
What is the use of System.in.read() in java?
Please explain this.
Two and a half years late is better than never, right?
int System.in.read() reads the next byte of data from the input stream. But I am sure you already knew that, because it is trivial to look up. So, what you are probably asking is:
Why is it declared to return an int when the documentation says that it reads a byte?
and why does it appear to return garbage? (I type '9', but it returns 57.)
It returns an int because besides all the possible values of a byte, it also needs to be able to return an extra value to indicate end-of-stream. So, it has to return a type which can express more values than a byte can.
Note: They could have made it a short, but they opted for int instead, possibly as a tip of the hat of historical significance to C, whose getc() function also returns an int, but more importantly because short is a bit cumbersome to work with, (the language offers no means of specifying a short literal, so you have to specify an int literal and cast it to short,) plus on certain architectures int has better performance than short.
It appears to return garbage because when you view a character as an integer, what you are looking at is the ASCII(*) value of that character. So, a '9' appears as 57. But if you cast that integer to a character, you get '9', so all is well.
Think of it this way: if you typed the character '9' it is nonsensical to expect System.in.read() to return the number 9, because then what number would you expect it to return if you had typed an 'a'? Obviously, characters must be mapped to numbers. ASCII(*) is a system of mapping characters to numbers. And in this system, character '9' maps to number 57, not number 9.
(*) Not necessarily ASCII; it may be some other encoding, like UTF-16; but in the vast majority of encodings, and certainly in all popular encodings, the first 127 values are the same as ASCII. And this includes all english alphanumeric characters and popular symbols.
May be this example will help you.
import java.io.IOException;
public class MainClass {
public static void main(String[] args) {
int inChar;
System.out.println("Enter a Character:");
try {
inChar = System.in.read();
System.out.print("You entered ");
System.out.println(inChar);
}
catch (IOException e){
System.out.println("Error reading from user");
}
}
}
System is a final class in java.lang package
code sample from the source code of api
public final class System {
/**
* The "standard" input stream. This stream is already
* open and ready to supply input data. Typically this stream
* corresponds to keyboard input or another input source specified by
* the host environment or user.
*/
public final static InputStream in = nullInputStream();
}
read() is an abstract method of abstract class InputStream
/**
* Reads the next byte of data from the input stream. The value byte is
* returned as an <code>int</code> in the range <code>0</code> to
* <code>255</code>. If no byte is available because the end of the stream
* has been reached, the value <code>-1</code> is returned. This method
* blocks until input data is available, the end of the stream is detected,
* or an exception is thrown.
*
* <p> A subclass must provide an implementation of this method.
*
* #return the next byte of data, or <code>-1</code> if the end of the
* stream is reached.
* #exception IOException if an I/O error occurs.
*/
public abstract int read() throws IOException;
In short from the api:
Reads some number of bytes from the input stream and stores them into
the buffer array b. The number of bytes actually read is returned as
an integer. This method blocks until input data is available, end of
file is detected, or an exception is thrown.
from InputStream.html#read()
import java.io.IOException;
class ExamTest{
public static void main(String args[]) throws IOException{
int sn=System.in.read();
System.out.println(sn);
}
}
If you want get char input you have to cast like this: char sn=(char) System.in.read()
The value byte is returned as int in the range 0 to 255. However, unlike in other languages’ methods, System.in.read() reads only a byte at a time.
Just to complement the accepted answer, you could also use System.out.read() like this:
class Example {
public static void main(String args[])
throws java.io.IOException { // This works! No need to use try{// ...}catch(IOException ex){// ...}
System.out.println("Type a letter: ");
char letter = (char) System.in.read();
System.out.println("You typed the letter " + letter);
}
}
System.in.read() reads from the standard input.
The standard input can be used to get input from user in a console environment but, as such user interface has no editing facilities, the interactive use of standard input is restricted to courses that teach programming.
Most production use of standard input is in programs designed to work inside Unix command-line pipelines. In such programs the payload that the program is processing is coming from the standard input and the program's result gets written to the standard output. In that case the standard input is never written directly by the user, it is the redirected output of another program or the contents of a file.
A typical pipeline looks like this:
# list files and directories ordered by increasing size
du -s * | sort -n
sort reads its data from the standard input, which is in fact the output of the du command. The sorted data is written to the standard output of sort, which ends up on the console by default, and can be easily redirected to a file or to another command.
As such, the standard input is comparatively rarely used in Java.
This example should help? Along with the comments, of course >:)
WARNING: MAN IS AN OVERUSED FREQUENT WORD IN THIS PARAGRAPH/POST
Overall I recommend using the Scanner class since you can input large sentences, I'm not entirely sure System.in.read has such aspects. If possible, please correct me.
public class InputApp {
// Don't worry, passing in args in the main method as one of the arguments isn't required MAN
public static void main(String[] argumentalManWithAManDisorder){
char inputManAger;
System.out.println("Input Some Crap Man: ");
try{
// If you forget to cast char you will FAIL YOUR TASK MAN
inputManAger = (char) System.in.read();
System.out.print("You entererd " + inputManAger + " MAN");
}
catch(Exception e){
System.out.println("ELEMENTARY SCHOOL MAN");
}
}
}
It allows you to read from the standard input (mainly, the console). This SO question may helps you.
System.in.read() is a read input method for System.in class which is "Standard Input file" or 0 in conventional OS.
system.in.read() method reads a byte and returns as an integer but if you enter a no between 1 to 9 ,it will return 48+ values because in ascii code table ,ascii values of 1-9 are 48-57 .
hope , it will help.
I'm running into a bit of an issue with determining if the user input is an int or double.
Here's a sample:
public static int Square(int x)
{
return x*x;
}
public static double Square(double x)
{
return x*x;
}
I need to figure out how to determine based on the Scanner if the input is a int or double for the above methods. However since this is my first programming class, I'm not allowed to use anything that hasn't been taught - which in this case, has been the basics.
Is there anyway of possibly taking the input as a String and checking to see if there is a '.' involved and then storing that into an int or double?
Lastly, I'm not asking for you to program it out, but rather help me think of a way of getting a solution. Any help is appreciated :)
The Scanner has a bunch of methods like hasNextInt, hasNextDouble, etc. which tell you whether the "next token read by the Scanner can be interpreted as a (whatever)".
Since you mentioned you've learned about the Scanner object, I assume the methods of that class are available to you for your use. In this case, you can detect if an input is an integer, double, or just obtain an entire line. The methods you would most be interested here would be the hasNextDouble() method (returns a boolean indicating whether or not the current token in the Scanner is actually a double or not) and the nextDouble() method (if the next token in the Scanner is in fact a double, parse it from the Scanner as one). This is probably the best direction for determining input types from a file or standard input.
Another option is to use the wrapper classes static methods for converting values. These are generally named like Integer.parseInt(str) or Double.parseDouble(str) which will convert a given String object into the appropriate basic type. See the Double classes method pasrseDouble(String s) for more details. It could be used in this way:
String value = "123.45"
double convertedValue = 0.0;
try {
convertedValue = Double.parseDouble(value);
} catch (NuberFormatException nfe) {
System.err.println("Not a double");
}
This method is probably best used for values that exist within the application already and need to be verified (it would be overkill to construct a Scanner on one small String for this purpose).
Finally, yet another potential (but not very clean, straightforward, or probably correct technique) could be looking at the String object directly and trying to find if it contains a decimal point, or other indicators that it is in fact a double. You may be able to use indexOf(String substr) to determine if it appears in the String ever. I suspect this method has a lot of potential problems though (say for example, what if the String has multiple '.' characters?). I wouldn't suggest this route because it is error prone and hard to follow. It might be an option if that's what the constraints are, however.
So, IMHO, your options should go as follow:
Use the Scanner methods hasNextDouble() and nextDouble()
Use the wrapper class methods Double.parseDouble(String s)
Use String methods to try and identify the value (avoid this technique at all costs if either of the above options are available).
Since you think you won't be allowed to use the Scanner methods there are a number of alternatives you try. You mentioned checking to see if a String contains a .. To do this you could use the contains method on String.
"Some words".contains("or") // evaluates to true
The problem with this approach is that there are many Strings that contain . but aren't floating point numbers. For examples, sentences, URLs and IP addresses. However, I doubt you're lecturer is trying to catch you out with and will probably just be giving you ints and doubles.
So instead you could try casting. Casting a double to an int results in the decimal portion of the number being discarded.
double doubleValue = 2.7;
int castedDoubleValue = (int) doubleValue; // evaluates to 2
double integerValue = 3.0;
int castedIntegerValue = (int) integerValue; // evaluates to 3
Hopefully, that should be enough to get you started on writing a solution to the problem.
Can be checked like this
if(scanner.hasNextDouble()}
{
System.out.println("Is double");
}
if(scanner.hasNextDouble()}
{
System.out.println("Is double");
}