Sentinal While Loop RTE - java

I have been trying to write a sentinal controlled while loop in java to add numbers, which are taken as input by the user. The loop must end when the user
enters "add".
The code is given below, the code does not show any compile error but there's a runtime Error. I would like to know what was the mistake I have done.
Thank you
// Sentinal while is used if we dont know how many numbers we are going to add
import javax.swing.JOptionPane;
public class sentinalWhile {
public static void main(String[] args)
{
String numberStr;
double number,total=0;
final String SENTINAL = "add";
numberStr = JOptionPane.showInputDialog("Enter a number to add (press add to quit):");
number = Double.parseDouble(numberStr);
while(numberStr.compareTo(SENTINAL)!=0)
{
total += number ;
numberStr = JOptionPane.showInputDialog("Enter a number to add(-999 to quit)");
number = Double.parseDouble(numberStr);
}
JOptionPane.showMessageDialog(null, "The total is:"+" "+total);
System.exit(0);
}
}
Error:
Exception in thread "main" java.lang.NumberFormatException: For input string: "add"
at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
at sun.misc.FloatingDecimal.parseDouble(Unknown Source)
at java.lang.Double.parseDouble(Unknown Source)
at sentinalWhile.main(sentinalWhile.java:11)

You need to remove "add" from the end of the string that you receive from the input dialog.
numberStr = numberStr.substring(0, numberStr.lastIndexOf("add"));
Then try to parse the double out of this string.
number = Double.parseDouble(numberStr);
Note that if the user enters a non-number string in the input dialog (e.g. 234sdfsf5500add), you will still get that exception. However, it will work fine for the normal inputs (100add).

Related

While loop issues with reading the tokens

I'm trying to read a list of tokens from a text file into separate variables by using a while loop.
Each line in the text file goes: String, Double, Int, Int, Boolean, and there are 11 lines, but I receive an InputMisMatchException for the double line after the String line.
The txt file reads as
AC 120.99 423 70 false
Toaster 18.99 101 30 true
Toaster 11.97 201 100 false
Yoyo 5.99 223 68 false
etc.
I've tried reading the file with .hasNext and .hasNextLine. When changing the double to String I get the error for the next Int and changing that to String again takes the error to the next Int but changing that does not move the exception further.
while (infp.hasNextLine() && count < LIMIT) {
String Product_description = infp.next();
double cost_per_item = infp.nextDouble(); //line 43
int product_id = infp.nextInt();
int quantity_at_hand = infp.nextInt();
boolean domestic_origin = infp.hasNext();
items[count] = new Item(Product_description, cost_per_item,
product_id, quantity_at_hand,
domestic_origin);
count++;
}
It's supposed to read all the tokens into variables and just create separate objects for each line in the text file. But from the error I believe it is only reading the first String then throwing the exception for the double.
The exception on line 43:
Exception in thread "main"
java.util.InputMismatchException at
java.util.Scanner.throwFor(Unknown Source) at
java.util.Scanner.next(Unknown Source) at
java.util.Scanner.nextDouble(Unknown Source) at DB_Master.main(DB_Master.java:43)
as you know nextDouble method is teruning a double value
double nextDouble()
Returns the next token as a long. If the next token is not a float or is out of range, InputMismatchException is thrown.
try give input in this format
like: 34,2 instead of 34.2
or try convert your Scanner with locale
Scanner scanner = new Scanner(System.in).useLocale(Locale.US);
An instance of this class is capable of scanning numbers in the standard formats as well as in the formats of the scanner's locale. A scanner's initial locale is the value returned by the Locale.getDefault() method; it may be changed via the useLocale(java.util.Locale) method
The localized formats are defined in terms of the following parameters, which for a particular locale are taken from that locale's DecimalFormat object, df, and its and DecimalFormatSymbols object, dfs.
for more ref see java docs
still not working try parsing by checking input type.
//************************************************************************
// MixedTypeInput
// This application demonstrates testing before reading to be
// sure to use the correct input method for the data.
//************************************************************************
import java.io.*;
import java.util.Scanner;
public class MixedTypeInput
{
public static void main(String[] args)
{
double number;
Scanner in = new Scanner(System.in);
System.out.println("Enter your gross income: ");
if (in.hasNextInt())
{
number = (double)in.nextInt();
System.out.println("You entered " + number);
}
else if (in.hasNextFloat())
{
number = (double)in.nextFloat();
System.out.println("You entered " + number);
}
else if (in.hasNextDouble())
{
number = in.nextDouble();
System.out.println("You entered " + number);
}
else
System.out.println("Token not an integer or a real value.");
}
}

How to check if a double value contains special characters

I was writing a code for a program in which the user enters 2 to 4 numbers which can be up to 2 decimal places long. However before the user enters these numbers they must enter the pound symbol, e.g. #12.34. I was wondering how i would check if the double value entered began with the pound sign, and if the user forgot to input it, to re-prompt them to do it again. So far im using a String value and the '.startsWith()' code, but I'm finding later on that a String value is making the rest of the program impossible to code, so i was wanting to keep it a double value. This is the code I have at the moment but wish to change to a double:
String input;
System.out.print("Enter the 4 numbers with a pound key: ");
input = keyboard.next();
while (!input.startsWith("#")) {
System.out.print("Re-enter the 4 numbers with a pound key: ");
input = keyboard.next();
}
I was wanting to replace the String with double as mentioned previously.
String input;
System.out.print("Enter the 4 numbers with a pound key: ");
input = keyboard.next();
while (!input.startsWith("#")) {
System.out.print("Re-enter the 4 numbers with a pound key: ");
input = keyboard.next();
}
// if your excution reaches here. then it means the values entered by user is starting from '#'.
String temp = input;
double value = Double.parseDouble(temp.replace("#",""));
For the rest of the program use value. I think the coding should be possible now.
A double value doesn't have a currency symbol. You should check for the currency symbol as you are doing and remove it before parsing the double.
String input;
System.out.print("Enter the 4 numbers with a pound key: ");
input = keyboard.next();
while (!input.startsWith("£")) {
System.out.print("Re-enter the 4 numbers with a pound key: ");
input = keyboard.next();
}
doulble number = Double.parseDouble(input.substring(1));
You should use the startsWith method. I don't know why you say that
I'm finding later on that a String value is making the rest of the program impossible to code
Basically, you want to prompt it repeatedly until the user enters the # sign. So why not use a while loop?
System.out.println("Enter a number:");
String s = keyboard.next();
double d = 0.0; // You actually wnat to store the user input in a
// variable, right?
while (!s.trim().startWith("#")) {
System.out.println("You did not enter the number in the correct format. Try again.");
s = keyboard.next();
try {
d = Double.parseDouble(s.substring(1));
} catch (NumberFormatException ex) {
continue;
} catch (IndexOutOfBoundsException ex) {
continue;
}
}
That's a lot of code!
Explanation:
First, it prompts the user to enter a number and store the input in s. That's easy to understand. Now here comes the hard part. We want to loop until the user enters the input with the correct format. Let's see what kind of invalid inputs are there:
The user does not enter a # sign
The user does not enter a number
The first one is handled by the startsWith method. If the input does not start with #, ask the user again. Before that, trim is first called to trim off whitespace in the input so that input like " #5.90" are valid. The second is handled by this part:
try {
d = Double.parseDouble(s.substring(1));
} catch (NumberFormatException ex) {
continue;
} catch (IndexOutOfBoundsException ex) {
continue;
}
If the input is in a wrong format, ask the user again. If the user enters a string with a length less than 1, ask the user again.
"But wait! Why is there a call to the substring method?" you asked. If the user does enter a # in the front, followed by a correct number format, how would you convert that string to a double? Here I just kind of trim the first character off by calling substring.
You could try something like this which removes all character that's not a number or a point:
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input;
System.out.println("Input a number: ");
while (!(input = br.readLine()).equals("quit")) {
Double parsedDouble;
if (input.matches("#[0-9]+\\.[0-9]{1,2}")) {
parsedDouble = Double.parseDouble(input.replaceAll("[^0-9.]+", ""));
System.out.println("double: " + parsedDouble);
System.out.println("Input another number: ");
} else {
System.out.println("Invalid. Try again. Example: #10.10");
}
}
}

How to check for user input without exiting for error

I need to check the user input and ask for a correct one if the value is not a digit. However when I do this code, the program displays an error message and then crashes- it does not ask the user to give a new input. How can that be fixed? Thank you!
import java.util.Scanner;
import java.lang.Math;
public class CentimeterInch
{
public static void main (String [] args)
{
final int MAX=100, feet=12, meter=100;
final double inch=2.54;
Scanner scan = new Scanner (System.in);
System.out.println ("This program converts distances. ");
System.out.println ("Enter distance and unit (e.g. 37 1 or 100 2):");
double distance=scan.nextDouble();
if (!scan.hasNextDouble())
{
System.out.println ("please enter a numeric value");
distance=scan.nextDouble();
}
int unitType = scan.nextInt();
if (distance<0)
{
System.out.println ("Please enter a non negative distance");
}
....
Just bring the if clause before performing scan.nextDouble().
if (!scan.hasNextDouble())
{
System.out.println ("please enter a numeric value");
scan.nextLine();
distance=scan.nextDouble();
}
double distance=scan.nextDouble();
First make sure that the number to be read is a double value, then read it. You were doing the reverse
What is scan.nextLine() doing here?
Suppose the user enters abc 2. scan.hasNextDouble() checks wether the token to be read next is a double value or not. It's not, so scan.hasNextDouble() evaluates to false and the if clause gets executed. Inside the if clause, you have scan.nextLine(). It simply discards the current input from scan, thus flushing scan. If you don't do so, then scan still contains abc 2 and upon executing distance = scan.nextDouble(), the compiler issues an error.
It's better if you replace if with while. Suppose user gives wrong input. Your program checks the input and finds out that it's not a double value. The if clause if executed and the user is asked to enter a numeric value. What if the user again enters a wrong input. This time, you will get an error. Using a while loop makes your program to keep asking the user for a correct input until he enters a numeric value.

ArrayIndexOutOfBoundsException on a Split String in a array

So I am doing some problems on the UVa online problem judge, but on a relativity easy problem, I keep on getting a ArrayIndexOutOfBoundsException. To understand the code, here is the problem.
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int t = scan.nextInt();
int sum = 0;
for (int i = 0; i <= t; i++){
String d = scan.nextLine();
if (d.equals("report")) {
System.out.println(sum);
} else {
String[] parts = d.split(" ");
int z = Integer.parseInt(parts[1]);
sum+=z;
}
}
}
}
The error message is:
reportException in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at Main.main(Main.java:16)
And I am using the sample input given.
Edit:
I have already tried added println statements in the code and figured out that the number is not being read. I am trying to understand why.
OK, after some messing around on my machine I think I found what might be at least part of the problem. The issue is that I'm not sure what the precise input is, so I'm going off of what I could get working on my machine.
So you start up your program, and it waits for a prompt at this line:
int t = scan.nextInt();
You enter your integer, and the program moves on as expected:
Input: 100 // Then press enter to continue
The input is parsed, and now t is set to 100.
Then when your program enters your for loop, it comes across this line:
String d = scan.nextLine();
Yet for some reason the program doesn't wait for input! (Or at least it didn't on my machine)
I believe the issue lies here:
Input: 100 // Then press enter to continue
^^^^^^^^^^^
What I think is happening is that your input is really
Input: 100\n
^^
That character (\r\n on Windows) is what's input when you hit enter. It's a newline character that tells the console to go to the next line.
So as a result, what I think happens is this:
Input: 100\n
Scanner parses 100, leaving the \n in the input stream
Then at the nextLine() call, the scanner sees \n on the input stream, which denotes end of line, so it thinks you already input the entire line! Because what it thought was your input was only the newline character, it returns an empty string, because your "input" was an empty string and the newline character. Your program then goes to split the newline character by spaces, rightly returns an array with a single element, and then your program promptly crashes when accessing an out-of-bounds index.
What might work better is reading an entire line first and parsing the integer so your scanner doesn't get ahead of itself, like this:
int t = Integer.parseInt(scan.nextLine());
Just as a warning: This is what I've been able to come up with based on using OP's code as-is on my machine. I was unable to get a situation where the only element in parts was "donate". I will update further as I get more info.
The error message means the array parts's length less than 2, sometimes.
It means the variable d does not always contain the string BLANK SPACE, " ", what you split by.
try this code:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int t = scan.nextInt();
int sum = 0;
for (int i = 0; i <= t; i++){
String d = scan.nextLine();
if (d.equals("report")) {
System.out.println(sum);
} else {
String[] parts = d.split(" ");
/*
* Add IF statement,
*/
if (parts.length() > 1) {
int z = Integer.parseInt(parts[1]);
sum+=z;
}
}
}
}
}

why's this program giving a runtime error on jcreator but not on netbeans?

This is my solution for sphere's online judge palin problem. It runs fine on Netbeans, but the judge is rejecting my answer saying it gives a RuntimeError. I tried it on JCreator and it says:
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 Main.main(Main.java:73)
I'm not passing an empty string for it to parse, why is this?
The code:
import java.io.*;
import java.util.*;
class Main {
public static int firstPalinLargerThanNum(int num){
int foundPalin =0;
int evalThisNum = ++num;
while (true){
if (isPalin(evalThisNum))
break;
evalThisNum++;
}
foundPalin = evalThisNum;
return foundPalin;
}
public static boolean isPalin(int evalThisNum){
boolean isItPalin = false;
int dig=0;
int rev=0;
int n = evalThisNum;
while (evalThisNum > 0)
{
dig = evalThisNum % 10;
rev = rev * 10 + dig;
evalThisNum = evalThisNum / 10;
}
if (n == rev) {
isItPalin=true;
}
return isItPalin;
}
public static void main(String args[]) throws java.lang.Exception{
BufferedReader r1 = new BufferedReader(new InputStreamReader(System.in));
/*BufferedReader r1 = new BufferedReader (new FileReader(new File ("C:\\Documents and Settings\\Administrator\\My Documents\\NetBeansProjects\\Sphere\\src\\sphere\\sphere\\PALIN_INPUT.txt")));*/
String read = r1.readLine();
int numberOfTestCases = Integer.parseInt(read);
for (int i=0; i<numberOfTestCases;i++){
read = r1.readLine();
if (read!=null){
int num = Integer.parseInt(read);
System.out.println(firstPalinLargerThanNum(num));
}
}
}
}
Input:
2
808
2133
line 73 is: int num = Integer.parseInt(read);
You will get that error if you hit <Enter> when the program is expecting a number.
Suppose your input is
2
3
<Enter>
You will receive the error you have indicated after processing the number 3, as you have told your routine to iterate twice.
As an aside, on top of error handling around the number parsing, you might also want to introduce a trim() to the readLine() method calls:
String read = r1.readLine().trim();
This will allow you to handle gracefully the input in the event that the user to put in whitespace around the numbers.
Just a wild guess: Could there be a problem with different end-of-line separators.
E.g. your program actually gets 2<CR><LF>808<CR><LF>2133<CR><LF>, thinks that the line ends at the <CR> and processes the line.
Now when it tries to process the next line it finds <LF> which makes it think it read an empty String.
You cannot assume that the user knows how to use your program and will give you correct input. The judge probably hit enter, without typing any number. How is he/she supposed to know the input that your program requires? A program should fail gracefully, not blow up in the user's face with cryptic errors.
You should be doing something like the following, so that the user knows what to do:
private static function readInt(BufferedReader reader) throws IOException
{
boolean done = false;
int result = -1;
while ( ! done ){
System.out.print("Please enter an integer: ");
String str = reader.readLine();
try{
result = Integer.parseInt(str);
done = true;
}catch(NumberFormatException cantconvert){
System.out.println("That isn't an integer. Try again.");
}
}
return result;
}
Additionally, you shouldn't use an exception specifier with the main function (that is, don't use "throws" in the signature of "main"). You should handle those IOExceptions and print a pretty and intelligible message to the user, even if there is nothing you can do about the exception to fix it or make it go away.
I just ran your example code under Eclipse 3.4 without error. I was only able to induce a similar error when I did not provide the specified number of test cases, i.e.:
6
56
87
[Enter]
So I am inclined to agree with akf that there must be an extra Enter happening somewhere, because this error will only be generated when there are insufficient lines of input.

Categories

Resources