Reading arguments from accepted scanner - java

I've been assigned the simple task of:
1) Accepting a Scanner argument and reading space-separated words from it.
2) If a word is a valid real number such as 0.1 or -3.14159 or 87 then add the number onto a running total.
3) When there is no more input available in the scanner, return total.
This is the magic that I have produced so far:
public static double sumReal(Scanner input) {
while(input.hasNext()) {
}
}
I understand that "hasNext" returns a boolean, but how can I confirm that it is a double and not a string?
Any help greatly appreciated!

Maybe the hasNextDouble() - Method will do the trick.
//some code
while (input.hasNextDouble()) {
//do something
}

Use
while (isDouble(input.nextLine())) {
// your code
}
& add a method to check if a number is Double or not
public static boolean isDouble(String str) {
try {
Double.parseDouble(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}

Related

Trying to validate a passed value to a method

I have a program that is trying to validate a passed value. I want a user to input anything and the method that I pass it to will validate whether the input would work.
This is my code:
public static void main(String[]args) {
Scanner input = new Scanner(System.in);
ChequingAccount a = new ChequingAccount();
double deposit = inputCheck("Enter deposit amount: ", input);
a.setDeposit(deposit);
}
public static double inputCheck(String prompt, Scanner input) {
boolean userValid = false;
do {
System.out.print(prompt);
double user;
try {
user = input.nextDouble();
if (user < 0) {
throw new IllegalArgumentException("Value cannot be lower than 0");
}
userValid = true;
} catch (InputMismatchException e) {
System.out.println("The value entered is not a number");
user = inputCheck(prompt, input);
input.nextLine();
} catch (IllegalArgumentException ex) {
System.out.println(ex.getMessage());
user = inputCheck(prompt, input);
}
return user;
} while (!userValid);
}
The code works except for the fact that when the method catches the InputMismatchException, the code then will loop a bunch of times and breaks the program. I thought adding a doWhile loop would solve the issue but it didn't do anything.
you don't need a loop , you need recursion
public static double inputCheck(String prompt, Scanner input) {
double user;
try {
user = input.nextDouble();
if (user < 0) {
throw new IllegalArgumentException("Value cannot be lower than 0");
}
return user;
} catch (InputMismatchException e) {
System.out.println("The value entered is not a number");
return inputCheck(prompt, input);
} catch (IllegalArgumentException ex) {
System.out.println(ex.getMessage());
return inputCheck(prompt, input);
}
}
You're calling your own method from inside; the inputCheck method's code calls inputCheck. This is a somewhat creative way to write a loop.
You also have... a loop.
So you 2 loops, to do the job that one loop should do. That's why all heck breaks loose here. Pick one: Either use the do/while construct (so do not call yourself), or, don't loop, and call yourself. Either one can be made to work here.
The nextLine stuff is irrelevant and not the problem here (in general don't call that; just set the delimiter properly; call scanner.useDelimiter("\\r?\\n") and to get entire lines, use next(), not nextLine().
There are number of approaches that can work for this – iteration, recursion, exception catching, etc. Your solution is mixing several of them together which makes it harder to understand and also harder to fix.
Here is an example that uses a simple while loop, no recursion, no exception catching. It uses hasNextDouble() and, depending on the result, either proceeds to capture the double (by calling nextDouble()), or prints a message (along with consuming and ignoring whatever non-double token is present by calling next()).
public static double inputCheck(String prompt, Scanner input) {
while (true) {
System.out.print(prompt);
if (input.hasNextDouble()) {
double number = input.nextDouble();
if (number < 0) {
System.out.println("Value cannot be lower than 0. Please try again.");
} else {
return number;
}
} else {
System.out.println("The value entered is not a number. Please try again.");
input.next(); // consume and ignore whatever non-double input is waiting on the scanner
}
}
}

I am trying to create a simple number guessing game

I ask the user to input a number until the user finds it.
I'm having trouble validating every input whether the user is typing in a number or anything else like char or string.
So basically I'm trying to prevent any mismatch exception error.
If you're writing code to take input as an integer, then it should come as an error or not move on if it doesn't have an int as an input.
If you're writing code to take a char or a string as an integer, then you should use Integer.parseInt() to convert your input to an int value.
Try to parse the text as a number, and if it fails, catch the failure and prompt the user to reenter the number.
Should be enough of a hint to get you going.
You can try to parse the String as a double and catch a NumberFormatException which will indicate that the input is not a valid number.
private static boolean isNumber(String s){
try{
Double.parseDouble(s);
return true;
} catch (NumberFormatException e){
return false;
}
}
If you want to not allow the String "NaN" to be accepted as a number, you can check if the String is equal to "NaN" before parsing it.
private static boolean isNumber(String s){
if(s.trim().equals("NaN")){
return false;
}
try{
Double.parseDouble(s);
return true;
} catch (NumberFormatException e){
return false;
}
}

How to get this piece of code into loop, so that it asks a user input each time until the result is "kill"?

I was practicing this piece of code from the book 'Head First Java' and I'm quite confused on the positioning of the loop here.The code is for creating a kind of game that has a random dotcom word(ex: abc.com) occupying some array elements. here I gave that dotcom word the positions from 3 to 5 in the array, and the user tries guessing the position.
import java.util.Scanner;
public class RunTheGame {
public static void main(String[] args) {
MainGameClass sampleObj= new MainGameClass();
int[] location = {3,4,5};
sampleObj.setdotcomLocationCells(location);
Scanner input= new Scanner(System.in);
System.out.println("Enter your guess");
int userGuess=input.nextInt();
String answer = sampleObj.checkForDotcom(userGuess);
System.out.println(answer);
}
}
package simpleDotComGame;
public class MainGameClass {
int[] DotcomLocationCells;
int numOfHits=0;
public void setdotcomLocationCells(int[] location) {
DotcomLocationCells= location;
}
public String checkForDotcom(int userGuess) {
String result="miss";
for(int cell:DotcomLocationCells) {
if(cell == userGuess) {
result ="hit";
numOfHits++;
break;
}
} // end for loop
if(numOfHits == DotcomLocationCells.length) {
result = "kill";
System.out.println("The number of tries= "+numOfHits);
}
}
do {
<insert code where answer result is created>
} while (!answer.equals("kill"))
upd.: but you must override the equals method for correct use, because if you see how method declared in Object.class you find
public boolean equals(Object obj) {
return (this == obj);
You are allowed to declare the variable before initializing it:
String answer;
do {
answer = sampleObj.checkForDotcom(userGuess);
System.out.println(answer);
} while (!answer.equals("kill");
Also beware of the semantics of Scanner.nextInt(): if it can't parse the input as an int (for example, it contains letters), it will throw an exception, but won't jump over the invalid input. You'll have to use Scanner.nextLine() to force-jump over it, otherwise you'll get an infinite loop.
Rachna, the loop will be positioned, around the following code:
Scanner input= new Scanner(System.in);
System.out.println("Enter your guess");
int userGuess=input.nextInt();
String answer=sampleObj.checkForDotcom(userGuess);
System.out.println(answer);
//For string you must use the equals
if ("kill".equals(answer)){
break;
}
The reason why is that the kill command must be evaluated inside the loop to break it, and the input to continuously ask the user input until he hits all targets.
Here's how the loop should be positioned.
String answer = "";
do{
System.out.println("Enter your guess");
int userGuess=input.nextInt();
answer=sampleObj.checkForDotcom(userGuess);
System.out.println(answer);
}
while(!answer.equals("kill"));
NOTE: Never Check for String equality using == in Java unless you know what you're doing (also read as, unless you know the concept of String Constant Pool).

Verify if a String is an integer (numberFormatException)

I was trying to write a piece of code to test if a string contains an integer. I am aware of the try catch solution, but i have read it becomes bad if you call the method from other classes. What I have read is that the method will show the error, but the main of the class calling it will keep running anyway.
Therefore, I was trying to do it manually. My problem is that i am able to assess that the string is not empty and that all the characters in the string are digits, but I can't find a way to verify whether the number is too big to be sorted in an integer. Point is, i have found on stackoverflow many similar topics, but noone solve this problem without try catch.
Here is my method.
// INTEGER VERIFICATION
public static boolean isInteger (String str_input){
int number_of_digits = 0;
if (str_input.isEmpty()) {
JOptionPane.showMessageDialog(null, "No input inserted", "Error", JOptionPane.ERROR_MESSAGE);
return false;
}
for (char c : str_input.toCharArray()){
if(Character.isDigit(c)){
number_of_digits++;
}
}
if (number_of_digits == str_input.length()){
return true;
}
else {
JOptionPane.showMessageDialog(null, "The input is not an integer", "Error", JOptionPane.ERROR_MESSAGE);
return false;
}
}
Thanks in advance for your help!
I think the best way to do this is as pointed by Leo in the comments.
public static boolean isInteger(final String strInput) {
boolean ret = true;
try {
Integer.parseInt(strInput);
} catch (final NumberFormatException e) {
ret = false;
}
return ret;
}
Also I suggest you separate the GUI part from the checking method, let the caller decide what to do if false (for example, maybe in some situations you want to check if it's an integer but don't show the dialog).
You could modify your method to make sure the number fits within an int.
It can be done by parsing the input as long, and checking against the range of int numbers.
// INTEGER VERIFICATION
public static boolean isInteger (String str_input){
int number_of_digits = 0;
if (str_input.isEmpty()) {
JOptionPane.showMessageDialog(null, "No input inserted", "Error", JOptionPane.ERROR_MESSAGE);
return false;
}
for (char c : str_input.toCharArray()){
if(Character.isDigit(c)){
number_of_digits++;
}
}
if (number_of_digits == str_input.length()){
if (str_input.length > 15) // arbitrary length that is too long for int, but not too long for long
return false;
long number = Long.parseLong(str_input);
if (number > Integer.MAX_VALUE || number < Integer.MIN_VALUE)
return false;
else
return true;
}
else {
JOptionPane.showMessageDialog(null, "The input is not an integer", "Error", JOptionPane.ERROR_MESSAGE);
return false;
}
}
BTW, if you allow negative inputs, you should change your check to allow '-' as the first character.
That said, I agree with all the comments that say you'd be better off to just call Integer.parseInt() and catch the exception.
How about using Regex
-?\\d+(\\.\\d+)? which accept negative and decimal numbers
Source: http://www.vogella.com/tutorials/JavaRegularExpressions/article.html
public static boolean isNumeric(String str) {
return str.matches("-?\\d+(\\.\\d+)?");
}

Extending java.util.Scanner

Suppose I would like to add a method to Scanner called nextPositiveInt() which is similar to nextInt() except that when a negative integer is detected, a custom InputNegativeException is thrown.
Why would I want to do this when there are solutions that utilise hasNextInt()? While being a little less concise, it seems a whole lot tidier and more logical given the purpose of exceptions. For example:
Extended Scanner method:
Scanner cli = new Scanner(System.in);
boolean inputValid = false;
do
{
System.out.println("Enter your age:");
try
{
int age = cli.nextPositiveInt();
}
catch(InputNegativeException e)
{
System.out.println("You cannot specify a negative age.");
inputValid = false;
}
catch(InputMismatchException e)
{
System.out.println("Your input must be numeric.");
inputValid = false;
}
} while(!inputValid);
hasNext() method:
Scanner cli = new Scanner(System.in);
do
{
System.out.println("Please enter a positive number!");
while(!sc.hasNextInt())
{
System.out.println("That's not a number!");
sc.next(); // this is important!
}
int number = sc.nextInt();
} while(number <= 0);
So assuming you aren't already firing up a response telling me why this is a very bad idea (if it is, please do; I imagine there might be some objection regarding putting validation in Scanner) I'm confused about how to go about this. I guess I need to replicate the body of nextInt() in nextPositiveInt() with some minor changes? Can you even source the body of nextInt() anywhere?
I apologise that I have no code to show any effort I've made but I'm not sure where to start.
Althought Scanner class is final and you cann't extend it there exist another solution. You can use Delegation pattern.
Also as Scanner class has all nessasary methods public you can easily copy original method and make a little change. See source code of Scanner class the only thing you should change is regexp used for matching string in order to exclude negative ints.
Source code of scanner:
public int nextInt() {
return nextInt(defaultRadix);
}
public int nextInt(int radix) {
// Check cached result
if ((typeCache != null) && (typeCache instanceof Integer)
&& this.radix == radix) {
int val = ((Integer)typeCache).intValue();
useTypeCache();
return val;
}
setRadix(radix);
clearCaches();
// Search for next int
try {
String s = next(integerPattern());
if (matcher.group(SIMPLE_GROUP_INDEX) == null)
s = processIntegerToken(s);
return Integer.parseInt(s, radix);
} catch (NumberFormatException nfe) {
position = matcher.start(); // don't skip bad token
throw new InputMismatchException(nfe.getMessage());
}
}
You should change only:
String s = next(integerPattern());
For you purposes you can hardcode regexp. Original regexp can easily be caught on debug.
Definitely it wouldn't be the best solution in terms of realization - a lot of code to write and many copy-paste, but it would be easy and nice to use.
You cannot extend Scanner since it's final:
public final class Scanner
extends Object
implements Iterator<String>
What I would do is have a helper method in one of my classes:
public static int ensureNonNegative(int val) {
if (val >= 0) {
return val;
} else {
throw new InputNegativeException(val);
}
}
and would use it like so:
int val = ensureNonNegative(scanner.nextInt());

Categories

Resources