Java System.out.println Prints 20 times - java

import java.util.*;
public class ArrayExample {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
boolean done = false;
while (!done) {
try {
System.out.println("Please enter the size of the array:");
String input = keyboard.next();
int size = new Integer(input).intValue();
int numbers[] = new int[size];
for (int i = 0; i < 20; i++) {
numbers[i] = i;
done = true;
System.out.println("Good.");
}
} catch (NumberFormatException ex) {
System.out.println("NumberFormatException Error. Please enter a integer.");
} catch (ArrayIndexOutOfBoundsException ex) {
System.out.println("ArrayIndexOutOfBoundsException Error. Please enter 20 or higher.");
} catch (NegativeArraySizeException ex) {
System.out.println("NegativeArraySizeException Error. Please do not enter a negative.");
}
}
}
}
When I run this program it does not function properly. It should throw a exception unless I enter a INTEGER 20 or higher. However, it prints "Good." if I enter a number lower then 20. So if I enter 19 it will print "Good." 19 times. If I enter 3 it will print "Good." 3 times. I only want it to print "Good." if I enter 20 or higher. If not it should continue to loop through the exceptions.

You don't need anArray and IndexOutOfBoundException
for (int i = 0; i < size; i++) // < --- use (size) instead of constant 20 value
{
System.out.println("Good.");
}
also add finally block with done = true;
}
finally
{
done = true;
}
This will prevent the infinite loop throwing an exception.
Also add validation at the beginning of the program:
int size = new Integer(input).intValue();
if (size >= 20)
{
throw new IllegalArgumentException("Number more then 19");
}

I didn't understand fully, but what I have got this program to do is if the number is less than 20, it will throw the ArrayIndexOutOfBoundsException, but if it is 20 or greater, it will print out "Good" for how many ever times the integer size was. I also changed the for loop into an enhanced for loop:
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
boolean done = false;
while (!done) {
try {
System.out.println("Please enter the size of the array:");
String input = keyboard.next();
int size = new Integer(input).intValue();
int numbers[] = new int[size];
if(numbers.length >= 20) {
for (int i : numbers) {
numbers[i] = i;
done = true;
System.out.println("Good.");
}
} else {
throw new ArrayIndexOutOfBoundsException("ArrayIndexOutOfBoundsException Error. Please enter 20 or higher.");
}
} catch (NumberFormatException ex) {
System.out.println("NumberFormatException Error. Please enter a integer.");
} catch (NegativeArraySizeException ex) {
System.out.println("NegativeArraySizeException Error. Please do not enter a negative.");
}
}
}

try the below code, you need to check if number given number is less than 20 and throw the exception, that part of code is missing
import java.util.*;
public class ArrayExample {
private static Scanner keyboard;
public static void main(String[] args) throws Exception {
keyboard = new Scanner(System.in);
boolean done = false;
while (!done) {
try {
System.out.println("Please enter the size of the array:");
String input = keyboard.next();
int size = new Integer(input).intValue();
int numbers[] = new int[size];
if(size <20){
throw new Exception("Number less than 20");
}
for (int i = 0; i < 20; i++) {
numbers[i] = i;
done = true;
System.out.println("Good.");
}
} catch (NumberFormatException ex) {
System.out.println("NumberFormatException Error. Please enter a integer.");
} catch (ArrayIndexOutOfBoundsException ex) {
System.out.println("ArrayIndexOutOfBoundsException Error. Please enter 20 or higher.");
} catch (NegativeArraySizeException ex) {
System.out.println("NegativeArraySizeException Error. Please do not enter a negative.");
}
}
}
}

The easiest way to answer this is to just walk through the code and figure out exactly what is happening. For simplicity, let's say you enter three.
import java.util.*;
public class ArrayExample {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
boolean done = false; //ok so we set done to false
while (!done) { //first time through, we are not done, so we enter the loop
try {
System.out.println("Please enter the size of the array:"); //you ask for a number
String input = keyboard.next(); //we put in '3'
int size = new Integer(input).intValue(); //convert the input to an int
int numbers[] = new int[size]; //we set the size to '3'
for (int i = 0; i < 20; i++) { //we enter the loop, i is 0 so we continue
numbers[i] = i; //we set the value of idx 0 to 0
done = true; //we set done to true so we will exit the while loop
System.out.println("Good."); //we print good
//we increment i to 1
}
//EXPANDED LOOP FOR CLARITY
for (int i = 0; i < 20; i++) { //second time, i is now 1
numbers[i] = i; //we set the value of idx 1 to 1
done = true; //we set done to true again (kind of redundant)
System.out.println("Good."); //we print good
//we increment i to 2
}
for (int i = 0; i < 20; i++) { //third time, i is now 2
numbers[i] = i; //we set the value of idx 2 to 2
done = true; //we set done to true again (still kind of redundant)
System.out.println("Good."); //we print good
we increment i to 3
}
for (int i = 0; i < 20; i++) { //fourth time, i is now 3
numbers[i] = i; //at this point we should throw an ArrayIndexOutOfBoundsException, so go to that catch statement
done = true;
System.out.println("Good.");
}
} catch (NumberFormatException ex) {
System.out.println("NumberFormatException Error. Please enter a integer.");
} catch (ArrayIndexOutOfBoundsException ex) { //so here we catch the AIOB exception
System.out.println("ArrayIndexOutOfBoundsException Error. Please enter 20 or higher."); //we print out an error, then continue
} catch (NegativeArraySizeException ex) {
System.out.println("NegativeArraySizeException Error. Please do not enter a negative.");
}
//here at the end of the block, we go back to check the while condition
//we set done to true, so the while will fail and we will exit the program
}
}
}
Given that, your output should look like this:
Good
Good
Good
ArrayIndexOutOfBoundsException Error. Please enter 20 or higher.
And that's all. The program will be done. Because you haven't posted the output, it would be difficult to debug this further.

Add the following lines after int size = new Integer(input).intValue();
if(size<20)
throw new ArrayIndexOutOfBoundsException("size is not equal to or greater than 20");
It will throw an Exception if the Size is less than 20. And no need to write those try and catch methods.
Hope this helped you...

Related

Try / catch in a do-while loop to check user input (array) - wrong boolean initialization and position

I am a Java beginner and I am learning to manage Exceptions and 2D arrays.
I am doing an exercise to plot in a 2D array the result of the sales of different car models.
I have mixed the way to deal with Exception by using a try catch or by throwing a custom Exception. On a custom Exception I have an issue I am not able to solve.
In the Seller class:
In line 16, IDE tells me that the variable "correct" initializer to
false is redundant
In line 26, IDE tells me that the while condition is always false.
I wanted to declare the boolean correct inside the inner loop to check for each value if the input was correct (an integer) or not and then to change the value to true at the end of the try in case the parseInt was successful. By reading the comments from the IDE I understand that the boolean correct is never changed to true even if I select an integer but I do not understand why.
import java.util.Scanner;
public class Sellers {
public static void main(String[] args) throws NumberArrayException {
Scanner myObj = new Scanner(System.in);
int nbrOfSellers = CheckInput.control("Enter the number of sellers = ");
int nbrOfModels = CheckInput.control("Enter the number of models = ");
int[][] sales = new int[nbrOfSellers][nbrOfModels];
String[] nameOfSellers = Characters.construction("seller", nbrOfSellers);
String[] nameOfModels = Characters.construction("model", nbrOfSellers);
for(int i = 0; i < nbrOfSellers; i++) {
for(int j = 0; j < nbrOfModels; j++) {
boolean correct = false;
System.out.print("Enter the sales for the seller " + nameOfSellers[i] + " for the model " + nameOfModels[i] + " = ");
do {
try {
String input = myObj.nextLine();
sales[i][j] = Integer.parseInt(input);
correct = true;
} catch (NumberFormatException e) {
throw new NumberArrayException();
}
}while (!correct) ;
}
}
for(int i = 0; i < nbrOfSellers; i++) {
for(int j = 0; j < nbrOfModels; j++) {
System.out.print(sales[i][j] + " ");
}
System.out.println();
}
}
}
import java.util.Scanner;
public class Characters {
public static String[] construction(String character, int maxSize) {
Scanner myObj = new Scanner(System.in);
String[] myArray = new String[maxSize];
for(int i = 0; i < maxSize; i++) {
System.out.print("Enter the name of the " + character + " ");
myArray[i] = myObj.nextLine();
}
return myArray;
}
}
import java.util.Scanner;
public class CheckInput {
public static int control(String message) {
boolean correct = false;
int number = -1;
Scanner myObj = new Scanner(System.in);
do {
try {
System.out.print(message);
String input = myObj.nextLine();
number = Integer.parseInt(input);
correct = true;
} catch(NumberFormatException e) {
System.out.println("Enter a number");
}
}while(!correct);
return number;
}
}
public class NumberArrayException extends RuntimeException {
public NumberArrayException() {
super();
}
}
There are two ways that this do-while-loop can exit: correct is true or an exception is thrown.
Technically, an exception can only be thrown in the two lines above the statement correct = true. Since you are throwing the NumberArrayException inside the loop, it will either exit because of it, or correct will be set true.
When we reach while (!correct), then correct is always true since it got set. Otherwise we would have exited with an exception. Therefore, this loop never has a second iteration.
To fix it, you can just avoid throwing an exception when the provided input cannot be parsed. The loop will then let the user enter another integer.
do {
try {
String input = myObj.nextLine();
sales[i][j] = Integer.parseInt(input);
correct = true;
} catch (NumberFormatException e) {
// output error message for the user here
}
} while (!correct);
Your code is pretty good and well structured. Actually, you should compare the source of CheckInput.control to see why it does not have the mentioned warnings: you initialize the local variable correct as it should be and no exception is thrown in case of invalid input, thus letting the user to correct it. If you throw an exception from inside do-while loop as in the main method, then the false value of correct is never used.
You should resolve these warnings by reusing existing CheckInput.control when initializing the 2D sales array. Also there's a typo when creating nameOfModels -- nbrOfModels should be passed as an argument.
String[] nameOfSellers = Characters.construction("seller", nbrOfSellers);
String[] nameOfModels = Characters.construction("model", nbrOfModels);
for(int i = 0; i < nbrOfSellers; i++) {
for(int j = 0; j < nbrOfModels; j++) {
sales[i][j] = CheckInput.control("Enter the sales for the seller " + nameOfSellers[i] + " for the model " + nameOfModels[i] + " = ");
}
}
When you throw an exception it exits the function and throws the exception. So instead of throwing the exception in the catch block just print and error message. So that user can understand the error and enter input again.
do {
try {
String input = myObj.nextLine();
sales[i][j] = Integer.parseInt(input);
correct = true;
} catch (NumberFormatException e) {
System.out.println("Wrong input format. Please enter a number");
}
}while (!correct) ;

JAVA: Problems with Exception-Handling? Program only catches Exception once

I'm attempting to create a program where the user enters a five-digit zip code from 00000 to 99999 and if the user enters a number out of that range or non-numeric values, it should throw an exception and give the user a chance to keep trying until they enter 5 numeric values.
My program only seems to catch the first instance of it, and afterwards it simply prints out the 2nd thing the user enters even if it doesn't fit the requirements.
I've just been stumped, and I'm not sure how I can use a while loop with my code, though I believe that's what I may need maybe?
I'm a beginner at this and any help would be appreciated!
import java.util.InputMismatchException;
import java.util.Scanner;
public class xzip_code {
public static void main(String[] args)
{
try
{
Bounds(Program());
}
catch(IllegalArgumentException ex)
{
System.out.println("Enter 5 Digits");
Program();
}
catch(InputMismatchException ex)
{
System.out.println("Enter Numbers");
Program();
}
}
public static void Bounds(String answer)
{
int length = answer.length();
if(length<5 || length>5)
{
throw new IllegalArgumentException("Enter 5 Digits");
}
char a = answer.charAt(0);
char b = answer.charAt(1);
char c = answer.charAt(2);
char d = answer.charAt(3);
char e = answer.charAt(4);
int f = a;
int g = b;
int h = c;
int i = d;
int j = e;
if(f>58 || g>58 || h>58|| i>58||j>58)
{
throw new InputMismatchException("Enter Numbers");
}
}
public static String Program()
{
Scanner userInput = new Scanner(System.in);
String x = userInput.next();
System.out.println(x);
return x;
}
}
Your method Bounds() does the validation work.
Currently, in your catch block you are just calling Program(). Instead you need to call the Bounds() and pass parameter Program() to it.
The below code will loop until there is no exception (successful try block execution).
boolean flag = true;
while(flag) {
try {
Bounds(Program());
flag = false;
} catch(IllegalArgumentException ex) {
System.out.println("Enter 5 Digits");
}
catch(InputMismatchException ex) {
System.out.println("Enter Numbers");
}
}
You also need to check if user has entered only numbers.
ASCII value of 0 -> 48 and 9 -> 57. Therefore, your check of > 58 makes no sense. It should check within the range.
You can simple use if (Character.isLetter(answer.charAt(index))) to check for individual digits (which is tedious).
Instead, just convert the String to Integer and check if it successfully gets converted otherwise throw error.
try {
Integer.parseInt(answer);
} catch (NumberFormatException e) {
throw new InputMismatchException("Enter Numbers");
}
You need to call Bounds(Program()); untill your program throws no error.
For that I created while loop that verifies if boolean isError is true.
To check if entered char is digit you can use Character.isDigit method.
See correct code:
package com.stackoverflow.main;
import java.util.InputMismatchException;
import java.util.Scanner;
public class xzip_code {
public static void main(String[] args) {
System.out.println("Enter 5 Digits");
boolean isError = true;
while (isError) {
try {
Bounds(Program());
} catch (IllegalArgumentException ex) {
System.out.println("Enter 5 Digits");
continue;
} catch (InputMismatchException ex) {
System.out.println("Enter Numbers");
continue;
}
isError = false;
}
}
public static void Bounds(String answer) {
int length = answer.length();
if (length < 5 || length > 5) {
throw new IllegalArgumentException("Enter 5 Digits");
}
char a = answer.charAt(0);
char b = answer.charAt(1);
char c = answer.charAt(2);
char d = answer.charAt(3);
char e = answer.charAt(4);
if (!(Character.isDigit(a) && Character.isDigit(b) && Character.isDigit(c) && Character.isDigit(d)
&& Character.isDigit(e))) {
throw new InputMismatchException("Enter Numbers");
}
}
public static String Program() {
Scanner userInput = new Scanner(System.in);
String x = userInput.next();
System.out.println(x);
return x;
}
}
Prints:
Enter 5 Digits
ewewdsddd
ewewdsddd
Enter 5 Digits
dffdffg
dffdffg
Enter 5 Digits
443446665
443446665
Enter 5 Digits
4444q
4444q
Enter Numbers
33333
33333
You need to make your catch a recursive call. The way you wrote it, it is caught, tries again, then ends.
Try to do it like this.
void foo() {
try {
bar();
} catch (Exception e) {
// try again
foo();
}
}
It also may be a good idea to keep track of how many times you retry. This could easily cause a StackOverflowError if you get it wrong too many times. I want to say the number is about 8 or 9 thousand.
Another option would be to use a loop.
void foo() {
boolean success = false;
while(!success) {
success = tryFoo();
}
}
boolean tryFoo() {
try {
bar();
return true; // true for success
} catch (Exception e) {
return false; // false for failed
}
}

A tiny issue with exception handling interactment - not the correct output

package test5555;
import java.util.InputMismatchException;
import java.util.Random;
import java.util.Scanner;
public class Test5555 {
private static int[] randomInteger;
public static void main(String[] args) {
boolean validInput = false;
randomInteger = new int[100];
Random rand = new Random();
for (int i = 0; i < randomInteger.length; i++)
randomInteger[i] = rand.nextInt();
int indexPosition = 0;
Scanner input = new Scanner(System.in); {
System.out.println("Please enter an integer for the array index position: ");
while(!validInput)
{
try
{
indexPosition = input.nextInt();
validInput = true;
System.out.println(randomInteger[indexPosition]);
} catch ( InputMismatchException | IndexOutOfBoundsException ex) {
System.out.print("Please enter a valid integer between 0 and 100 or type quit to exit: ");
String s = input.next();
if(s.equals("quit")){
System.exit(0);
System.out.println(randomInteger[indexPosition]);
}
}
}
}
}
}
The code runs perfectly except for two minor hiccups that I cannot solve. When you run it you get Please enter an integer for the array index position:If you type a number above 100 or a string such as bob then you get Please enter a valid integer between 0 and 100 or type quit to exit:which is perfect. But if you type quit then you get Please enter a valid integer between 0 and 100 or type quit to exit: BUILD SUCCESSFUL (total time: 2 minutes 2 seconds) so it quits it but it repeats the exception statement which I do not want.
When you type a number above 100 and receive the Please enter a valid integer between 0 and 100 or type quit to exit: if you then type a correct integer the program will just turn off and it will say BUILD SUCCESSFUL instead of retrieving the number for you from the array
Replace your while loop code with below,
String s = null;
while(!validInput)
{
try
{
if(s != null){
indexPosition = Integer.parseInt(s);
}
else{
indexPosition = input.nextInt();
}
System.out.println(randomInteger[indexPosition]);
validInput = true;
} catch ( InputMismatchException | NumberFormatException | IndexOutOfBoundsException ex ) {
System.out.println("Please enter a valid integer between 0 and 100 or type quit to exit: ");
input.nextLine();
s = input.next();
if(s.equals("quit")){
System.exit(0);
}
}
}
Please read this to get more idea on Scanner.
https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html
In your case the problem is (As per doc)
When a scanner throws an InputMismatchException, the scanner will not
pass the token that caused the exception, so that it may be retrieved
or skipped via some other method.
The behavior you describe in point 1 us not correct. If you type in a number and then quit it works "as expected"
If you type in a string such as "bob" your nextInt() fails with an InputMissmatchException which means your "input.next()" call in the catch clause will read "bob" and see it's not equal to "quit" and just go back to the loop and block and wait for an "int".
In point 2. You type an int and you get an exception...but you've set validInput to true already so you'll exit the loop. You need to set validInput after you print.
If I got your question correctly, I would implement little differently. Please check if it fulfills your requirement.
import java.util.Random;
import java.util.Scanner;
public class Test5555 {
private static int[] randomInteger;
public static void main(String[] args) {
randomInteger = new int[100];
Random rand = new Random();
int indexPosition;
for (int i = 0; i < randomInteger.length; i++)
randomInteger[i] = rand.nextInt();
Scanner input = new Scanner(System.in);
System.out.println("Please enter an integer for the array index position: ");
while(true) {
String strIndex = input.next();
if(strIndex.equals("quit")) break;
indexPosition = getIntVal(strIndex);
if(indexPosition < 0 || indexPosition >= randomInteger.length) {
System.out.print("Please enter a valid integer between 0 and "
+ randomInteger.length + " or type quit to exit: ");
continue;
}
System.out.println(randomInteger[indexPosition]);
break;
}
input.close();
}
protected static int getIntVal(String inputStr) {
int result = -1;
try {
result = Integer.parseInt(inputStr);
} catch(NumberFormatException e) {}
return result;
}
}
This part of your code is wrong
try
{
indexPosition = input.nextInt();
validInput = true;
System.out.println(randomInteger[indexPosition]);
} catch ( InputMismatchException | IndexOutOfBoundsException ex) {
You are saying that your indexPosition is right before to check it, the line
validInput = true;
Should be later of check if the array have that position.
Right code:
...
indexPosition = input.nextInt();
System.out.println(randomInteger[indexPosition]);
validInput = true;
....

Why does it not display Exception error

List<String> AccountList = new ArrayList<String>();
AccountList.add("45678690");
AccountList.add("7878787");
Scanner AccountInput = new Scanner(System.in);
int x = 1;
do{
try{
System.out.println("Hi whats your pin code?");
String Value = AccountInput.nextLine();
for (int counter = 0; counter < AccountList.size(); counter++){
if (AccountList.contains(Value)){ //If Input = ArrayList number then display "hi"
System.out.println("Hi");
x = 2;
}
}
} catch (Exception e){
System.out.println("You cant do that");
}
}while (x==1);
}
}
When I run this the error "You cant do that" does not appear but it is taken invalid and asks user to re enter number untill valid, how can I get the error line to be displayed?
You need to throw an exception to be able to catch one:
for (int counter = 0; counter < AccountList.size(); counter++){
if (AccountList.contains(Value)) { //If Input = ArrayList number then display "hi"
System.out.println("Hi");
x = 2;
} else {
throw new Exception();
}
}
EDIT: As said in the comment, the for line is not necessary as the algorithm to know if the value is contained in your AccountList is handled by the contains method.

I'm trying to loop for a positive integer, but I keep getting exceptions in the main method even though I'm using a try-catch

Here's my code:
public static double[] getArrayInput() {
Scanner stdin = new Scanner(System.in);
int arrayLength;
double[] arrayInput;
try {
System.out.print("Please enter the length of the array: ");
arrayLength = stdin.nextInt();
while (arrayLength <= 0) {
System.out.print("Invalid input, please enter a positive integer: ");
arrayLength = stdin.nextInt();
}
}
catch (InputMismatchException ex) {
System.out.print("Invalid input, please enter a positive integer: ");
arrayLength = stdin.nextInt();
}
arrayInput = new double[arrayLength];
System.out.print("Please enter the array elements: ");
for (int i = 0; i < arrayLength; i++) {
do {
double j = stdin.nextDouble();
arrayInput[i] = j;
} while (arrayInput.length < arrayLength);
}
return arrayInput;
}
I need to be able to continuously prompt for an integer value if a non-integer is entered. I read online that you can use the scanner.hasNextInt() method to do this, but every time I try to implement it, I keep getting new exceptions in my main method.
Should I expect for an exception to go to my main method if I have a catch block in this method?
I did notice the problem and is marked here in the complete program:
As you will notice you will need to do stdin.nextLine() to skip the last invalid input from being read again by the scanner.
Other than that, there is a bit of refactoring to your code.
public static double attemptInputElement(Scanner stdin) {
try {
double j = stdin.nextDouble();
} catch (InputMismatchException ex) {
System.out.print("Invalid input, please enter a valid element");
stdin.nextLine(); // skip the last input
attemptInputElement(stdin);
}
return 0.0; // should never get reached.
}
public static double[] getArrayInput() {
Scanner stdin = new Scanner(System.in);
int arrayLength;
double[] arrayInput = null;
System.out.print("Please enter the length of the array: ");
try {
arrayLength = stdin.nextInt();
while (arrayLength <= 0) {
System.out.print("Invalid input, please enter a positive integer: ");
arrayLength = stdin.nextInt();
}
} catch (InputMismatchException ex) {
System.out.print("Invalid input, please enter a positive integer: ");
stdin.nextLine(); // skip the last input
arrayLength = stdin.nextInt();
}
arrayInput = new double[arrayLength];
System.out.print("Please enter the array elements: ");
for (int i = 0; i < arrayLength; i++) {
do {
arrayInput[i] = attemptInputElement(stdin);
} while (arrayInput.length < arrayLength);
}
return arrayInput;
}
Add:
catch(Exception e)
{
//catch all exceptions here
}
That way it won't go to Main.
Next, it seems un-necessary to have two loops just to fill in the array elements. And you also probably want to have a try/catch around that nextDouble()

Categories

Resources