try statement not being used on second illiteration of loop [duplicate] - java

This question already has answers here:
try/catch with InputMismatchException creates infinite loop [duplicate]
(7 answers)
Closed 7 years ago.
I am making a method in order to get how many numbers the user wants to sum together. aka if they want to sum the numbers 1 2 and 3. they would want to sum 3 numbers together. So when i ask them how many they want to sum together, I use a try - catch in order to catch if they enter a decimal place. Because you cant add together 3.5 numbers you can add 3 numbers or 4. problem is if the user enters a decimal, the program will infinite loop run everything but what is in the try statement. How can i fix this?
Here is the code for the method:
private static int requestMaxInputForFloat(Scanner scanner){
boolean appropriateAnswer = true; // assume appropriate catch not appropriate to loop again
int howManyInputs = 1000000; // hold value to return how many inputs. if this value we will not run.
//request an appropriate number of inputs until appropriate answer = true;
do
{
appropriateAnswer = true; //if looped again reset value to true
try{
System.out.print("How many decimal place numbers would you like to sum? ");
howManyInputs = scanner.nextInt();
}catch(Exception e){
System.out.println("Sorry but you can only request to average a whole number set of data.\nTry Again.");
appropriateAnswer = false;
}//end of try-catch
if (howManyInputs <= 0) //invalid answer
{
System.out.println("Sorry but " + howManyInputs + " is equal to or below 0. Please try again.");
}else{
appropriateAnswer = false;
}
}while(!appropriateAnswer);//end of while loop
return howManyInputs; //return the value
}// end of getMaxInput

Add scanner.nextLine(); in the catch block. I think the problem is that if nextInt() gets an error, the scanner's "pointer" is still pointing at a bad character, and if you just try nextInt() again, it will try to scan the same bad character over again. You have to do something to make the scanner skip over it. Here, you want to just throw away whatever the user typed in, so nextLine(), which skips over the entire remainder of the input line, is the most appropriate.
One other thing: I'd change
if (howManyInputs <= 0) //invalid answer
to
if (appropriateAnswer && howManyInputs <= 0) //invalid answer
Otherwise, if the user types in -1, then the loop will go back and howManyInputs will still be -1; then if the user types 3.5, you'll get the exception but you'll get a second error message because howManyInputs is still -1 left over from the previous loop. You don't need to test howManyInputs if you already know there was an input error.

Related

Java infinite loop, while validation [duplicate]

This question already has an answer here:
Exception handling infinite loop
(1 answer)
Closed 5 years ago.
This is a part of my code which is used to validate an input and loop if it is a character, however it causes an infinite loop when a character is input, but works fine when an integer is used. I don't know whats causing the infinite loop but any help would be appreciated.
System.out.println("Please type in a mark and enter -1 to end the program");
while (mark != -1) {
if (in.hasNextInt()) {
mark = in.nextInt();
}
else {
System.out.println("Please input an integer: ");
}
If you input a character the:
if (in.hasNextInt())
Will return false, and you go to the else, when it loops, the in.hasNextInt() is still false entering the else and looping forever.

While loop breaks after bufferedInput change [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 6 years ago.
I'm doing some basic homework, and it's honestly all stuff I know. But I decided to jazz it up a little, and something I'm missing is causing an unexpected error.
The idea is to use a while loop which asks if the user would like to do something. So long as they say yes, the loop continues the operations that it holds (in this case rounding a decimal to an int). However, as soon as I enter yes, or anything really, the loop breaks there and won't continue on to the rounding portion.
public class DecimalRounder {
//Main class method that starts and ends the program. It is prepared to throw an IO exception if need be.
public static void main(String args[])throws IOException
{
//Main initializes a new reader to take input from System.in
InputStreamReader rawInput = new InputStreamReader(System.in);
//Main then initializes a new buffer to buffer the input from System.in
BufferedReader bufferedInput = new BufferedReader(rawInput);
//Main initializes other used variable
double castInput = 0.0;
String contin = "yes";
//Program then sets up loop to allow user to round numbers till content
while (contin == "yes")
{
//Program asks user if they'd like to round.
System.out.println("Would you like to round? Type yes to continue... ");
contin = bufferedInput.readLine();
//If user says yes, rounding begins. ERROR FOUND HERE?
if (contin == "yes") //INPUT "yes" DOESN'T MATCH?
{
//Program then requests a decimal number
System.out.println("Please enter a decimal number for rounding: ");
String givenLine = bufferedInput.readLine();
//rawInput is worked on using a try catch statement
try {
//givenLine is first parsed from String into double.
castInput = Double.parseDouble(givenLine);
//castInput is then rounded and outputted to the console
System.out.println("Rounded number is... " + Math.round(castInput));
//Branch then ends restarting loop.
}catch(Exception e){
//If the data entered cannot be cast into a double, an error is given
System.err.println("That is not a roundable number: " + e.getMessage());
//And branch ends restarting loop.
}
}
}
System.out.println("Have a nice day!");
}
}
Use .equals instead of == to compare strings in JAVA.
Try this :
contin.equals("yes")

ArrayIndexOutOfBoundsException when putting strings split from an array into 3 others [duplicate]

This question already has answers here:
How can I avoid ArrayIndexOutOfBoundsException or IndexOutOfBoundsException? [duplicate]
(2 answers)
Closed 7 years ago.
Here is my code:
for (int i = 0; i < 99; i++)
{
String inputString = keyboard.next();
String[] inputArray = inputString.split(":");
if (inputString.equals("quit"))
System.out.println("You have quit");
FirstArray[i] = inputArray[0];
SecondArray[i] = Integer.parseInt(inputArray[1]); // these throw errors
ThirdArray[i] = Integer.parseInt(inputArray[2]);
System.out.println(FirstArray[i]);
System.out.println(SecondArray[i]);
System.out.println(ThirdArray[i]);
So here is my code, I'm trying to test out arrays and I need to get input from the user split using the delimiter ":"
I had to parseInt the last two arrays (as they are taking in integer values) to get the split input from the second and third index of the inputArray.
I have the last part of the code to test if it works, and it does but when I type in "quit" to end the loop it throws:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
I have searched and understood the issue but don't know how to avoid it. Sorry if I'm not explaining my issue, would appreciate another working solution. Thanks in advance for help
The string "quit" does not contain any ":" characters, so the result of inputString.split(":") is an array with a single element. So as soon as you try to access inputArray[1], you will have the exception, because index 1 refers to the 2nd element in the array, although this array has only one element
if (inputString.equals("quit")) {
System.out.println("You have quit");
return; // add this line
}
Add the return statement (shown above), and this will by pass the code problematic code. It seems like the right thing to do anyways, as the user is asking to quit the program.
Access inputArray only till its length i.e use inputArray.length() first to find array length then access array elements from 0 to length -1.
Most evident case from your code is when you enter quit but other inputs might cause it too since your are not checking length of array i.e. if length of splitted array is less that 3 for whatever input , you will receive this exception.
The issue you are running into is that the code accessing the inputArray variable is run regardless of whether or not the quit command is received. You have two options here.
1) Return on the quit command (recommended)
if (inputString.equals("quit")) {
System.out.println("You have quit");
return; // This will avoid running the code below
}
FirstArray[i] = inputArray[0];
SecondArray[i] = Integer.parseInt(inputArray[1]); // these throw errors
ThirdArray[i] = Integer.parseInt(inputArray[2]);
System.out.println(FirstArray[i]);
System.out.println(SecondArray[i]);
System.out.println(ThirdArray[i]);
2) Throw the remaining code in an else case
if (inputString.equals("quit")) {
System.out.println("You have quit");
} else {
FirstArray[i] = inputArray[0];
SecondArray[i] = Integer.parseInt(inputArray[1]); // these throw errors
ThirdArray[i] = Integer.parseInt(inputArray[2]);
System.out.println(FirstArray[i]);
System.out.println(SecondArray[i]);
System.out.println(ThirdArray[i]);
}
I would also recommend adding an error case if the inputArray doesn't end up being the expected length.
if (inputArray.length != 3) {
System.out.println("That's weird. I was expecting 3 parameters, but only found " + inputArray.length);
return;
}
you can use Scanner class to read the input.
Scanner scanner = new Scanner(System.in);
for(int i=0; i<Noofiterations; i++){ //iterations are the no.of times you need to read input.
String[] inputArray = scanner.nextLine().split(":");
//rest of the code is same as yours.
}
Input should be in the form "abc:123:334:wet"
Hope this helps. Let me know if i didn't get your question.

Get user to input integers

I want to make a program which keeps prompting the user to input integers(from CUI) until it receives a 'X' or 'x' from the user.
The program then prints out the maximum number, minimum number and average value of the input numbers.
I did manage to get the user to input numbers until someone types 'X', but I can't seem to get it to stop if someone types 'x' and the second bit.
This is the code that I have managed to work out:
Scanner in = new Scanner(System.in);
System.out.println("Enter a number")
while(!in.hasNext("X") && !in.hasNext("x"))
s = in.next().charAt(0);
System.out.println("This is the end of the numbers");
Any hints on how I proceed further?
You will need to do something like this:
Scanner in = new Scanner(System.in);
System.out.println("Enter a number")
while(!(in.hasNext("X") || in.hasNext("x")))
s = in.next().charAt(0);
System.out.println("This is the end of the numbers");
Whenever you use while loop you have to use the {} in case the arguments in the while block are more than 1 line, but if they are just of a line then you can just go on without using the {}.
But the problem, you had I suppose is the use of && instead of ||. What the && (AND) operator does is execute if both the statements are true but a || (OR) Operator works if any of the conditions are true.
If you say while(!in.hasNext("X") && !in.hasNext("x")) it makes no sense as the user input is not both at the same time, but instead if you usewhile(!in.hasNext("X") || !in.hasNext("x"))` it makes sense. Understood?
And about sorry, im really new at this. but ive added the code No problem, you need not say sorry but there are a few things to keep in mind before asking a question. You must read this https://stackoverflow.com/help/how-to-ask and yeah one more thing, you should use proper English Grammar while framing your question.
Last of all, about how to calculate the average..., for that what you need to do is store all the input variables into an array and then take out the mean of that or alternatively you could think about it and code something up yourself. Like to take out mean, you could make a variable sum and then keep adding the integers the user enters and also keep a variable count which will keep the count of the number of integers entered and then at last you could divide both of them to have your answer
Update: For checking the minimum and the maximum, what you can do is make 2 new variables like int min=0, max=0; and when the user enters a new variable you can check
//Note you have to change the "userinput" to the actual user input
if(min>userinput){
min=userinput;
}
and
if(max<userinput){
max=userinput;
}
Note: At stackoverflow we are there to help you out with the problems you are facing BUT you cannot exploit this. You cannot just post your homework here. But if you are trying to code something up and are stuck at it and cannot find a answer at google/stackoverflow then you can ask a new question and in that you need to tell what all you have already tried. Welcome to SO! :D Hope you have a nice time here
This would fit your needs:
public void readNumbers() {
// The list of numbers that we read
List<Integer> numbers = new ArrayList<>();
// The scanner for the systems standard input stream
Scanner scanner = new Scanner(System.in);
// As long as there a tokens...
while (scanner.hasNext()) {
if (scanner.hasNextInt()) { // ...check if the next token is an integer
// Get the token converted to an integer and store it in the list
numbers.add(scanner.nextInt());
} else if (scanner.hasNext("X") || scanner.hasNext("x")) { // ...check if 'X' or 'x' has been entered
break; // Leave the loop
}
}
// Close the scanner to avoid resource leaks
scanner.close();
// If the list has no elements we can return
if (numbers.isEmpty()) {
System.out.println("No numbers were entered.");
return;
}
// The following is only executed if the list is not empty/
// Sort the list ascending
Collections.sort(numbers);
// Calculate the average
double average = 0;
for (int num : numbers) {
average += num;
}
average /= numbers.size();
// Print the first number
System.out.println("Minimum number: " + numbers.get(0));
// Print the last number
System.out.println("Maximum number: " + numbers.get(numbers.size() - 1));
// Print the average
System.out.println("Average: " + average);
}

Try catch block causing infinite loop? [duplicate]

This question already has answers here:
try/catch with InputMismatchException creates infinite loop [duplicate]
(7 answers)
Closed 7 years ago.
I am writing a simple java console game. I use the scanner to read the input from the console. I am trying to verify that it I ask for an integer, I don't get an error if a letter is entered. I tried this:
boolean validResponce = false;
int choice = 0;
while (!validResponce)
{
try
{
choice = stdin.nextInt();
validResponce = true;
}
catch (java.util.InputMismatchException ex)
{
System.out.println("I did not understand what you said. Try again: ");
}
}
but it seems to create an infinite loop, just printing out the catch block. What am I doing wrong.
And yes, I am new to Java
nextInt() won't discard the mismatched output; the program will try to read it over and over again, failing each time. Use the hasNextInt() method to determine whether there's an int available to be read before calling nextInt().
Make sure that when you find something in the InputStream other than an integer you clear it with nextLine() because hasNextInt() also doesn't discard input, it just tests the next token in the input stream.
Try using
boolean isInValidResponse = true;
//then
while(isInValidResponse){
//makes more sense and is less confusing
try{
//let user know you are now asking for a number, don't just leave empty console
System.out.println("Please enter a number: ");
String lineEntered = stdin.nextLine(); //as suggested in accepted answer, it will allow you to exit console waiting for more integers from user
//test if user entered a number in that line
int number=Integer.parseInt(lineEntered);
System.out.println("You entered a number: "+number);
isInValidResponse = false;
}
//it tries to read integer from input, the exceptions should be either NumberFormatException, IOException or just Exception
catch (Exception e){
System.out.println("I did not understand what you said. Try again: ");
}
}
Because of common topic of avoiding negative conditionals https://blog.jetbrains.com/idea/2014/09/the-inspection-connection-issue-2/

Categories