How to ask for input until 2 integers are received? - java

I need to validate that user inputs two integers and as such, I need to continue asking him for input until he provides both inputs that are integers. Not sure how to implement it, but I came up with something like that but now struggling to implement the part that checks if coord1 and coord2 get correct types. If not, it of course gives me the NumberFormatException:
while (true) {
System.out.print("Enter the coordinates: ");
int coord1 = Integer.parseInt(scanner.next());
int coord2 = Integer.parseInt(scanner.next());
if (coord1 < 1 || coord1 > 3 || coord2 < 1 || coord2 > 3) {
System.out.println("Coordinates should be from 1 to 3!");
continue;
} else if (cellOccupied(field, coord1, coord2)) {
System.out.println("This cell is occupied! Choose another one!");
continue;
}
break;
}
Can I solve it without using try / catch, since I haven't learned that yet, or is this the only way?
Thank you in advance and sorry, since I'm still learning Java syntax and ways of validation.

Instead of manually checking if the input is the right type, you could rely on the Scanner's methods hasNextInt() and nextInt().
The first one will check whether your input is an actual int and then you can proceed reading it with nextInt(). For further details about placing a nextLine() after reading a numeric type read the following question asked here on stack overflow.
Here I've also included your code in a sample main. I know yours was just a snippet with much more code around (I didn't have the cellOccupied method, for example) but I've just pasted it like so for a minimal testing. Besides, I've also parameterized your use case. It was a bit odd and redundant to repeat the same code for reading the user input applying the same coordinate-logic.
public class Main {
public static void main(String[] args) {
int coord1 = 0, coord2 = 0;
do {
coord1 = readCoordinate("Enter first coordinate: ");
coord2 = readCoordinate("Enter second coordinate: ");
//Showing an error message if the coords refer to an occupied cell
if (cellOccupied(field, coord1, coord2)) {
System.out.println("This cell is occupied! Choose another one!");
}
} while (cellOccupied(field, coord1, coord2));
}
private static int readCoordinate(String message) {
int coord;
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.print(message);
if (scanner.hasNextInt()) {
coord = scanner.nextInt();
//getting rid of the new line character after reading the int
scanner.nextLine();
//Checking coordinate value
if (coord < 1 || coord > 3) {
System.out.println("Coordinates should be from 1 to 3!");
continue;
}
} else {
//assigning an undesired value (since your coords must be between 1 and 3
coord = 0;
//getting rid of the wrong user input
scanner.nextLine();
//Showing an error message
System.out.println("Please enter an int value");
//Skipping directly to the loop's condition
continue;
}
break;
}
return coord;
}
}
On a side note, avoid declaring fields in a loop.

You can find here several suggestions. For example, you can use regular expressions. Create an isNumeric function that will tell you whether a given string is an integer:
public boolean isNumeric(String strNum) {
Pattern pattern = Pattern.compile("\\d+");
if (strNum == null) {
return false;
}
return pattern.matcher(strNum).matches();
}
And before pushing the scanner.next() to the integer parser, check it with the function.

Related

Why does it take additional input for scanner to see an empty line?

public class Test1 {
public static void main(String[] args) {
System.out.println("Give me a word: ");
Scanner console = new Scanner(System.in);
ArrayList<String> arr = new ArrayList<>();
boolean found = true;
while (console.hasNextLine() && found) {
String line = console.nextLine();
if (line.equals("")) {
found = false;
} else {
arr.add(line);
}
}
System.out.println("You said: ");
for (int index = 0; index < arr.size(); index++) {
System.out.println(arr.get(index));
}
}
}
I'd like to print what user typed in whenever the user types enter twice, however this requires three enters to be inputted for some reason. When I remove the console.hasNextLine statement in while loop's condition, it works perfectly fine. Why is this the case?
console.hasNextLine() blocks application flow and waits for input to be received.
1st enter - word is found and found remains == true
2nd enter - word is not found and found is set to == false
3rd enter - is required because your booleans are evaluated in order which they are arranged. so first it'll call console.hasNextLine() and allow user to provide input. THEN it'll check if found == true/false which would == false and would break out of the loop.
an easy solution would be to rearrange your conditions to be
found && console.hasNextLine()

how to check if an input from a user is 1 integer

i am asking from the user to type a number and I need to check if the user's answer is only one integer
This is my code:
System.out.println("MENU:What do you want to do ? \n1.Buy a new ticket!\n2.Renewal of a ticket\n3.Update the content");
System.out.println("Type the number of what you want to do ");
if (!(input.hasNextInt() && input.hasNextByte())) { // if the input is not an integer and more than one byte
System.out.println("ERROR!!Enter an integer value ");
input.next();
} else {
int Read = input.nextInt(); //reads what the user has typed/given
System.out.println("You entered an integer value! ");
}
i have tried this, and it shows error (which menas it is working)for inputs like these: 34443 22123 cdsfr4d but when i give only 2 or 3 integers like: 34 or 567, it does not show me any error !HOw cam I cnage it in order to show me the correct message
Remove && input.hasNextByte()
I'm assuming you only want the user to input: 1, 2, or 3 since that's what I'm seeing in your Console menu.
The way I would handle this issue is by using a switch statement and a default case in case they enter anything else.
if (!(input.hasNextInt()) { // if the input is not an integer and more than one
System.out.println("ERROR!!Enter an integer value ");
input.next();
} else {
int choice = input.nextInt();
switch (choice) {
case 1: //If choice is 1
case 2: // If choice is 2
case 3: // If choice is 3
default: // If choice is any other integer
}
}
Switch statements are not commonly used in Java as there are usually better ways to handle these scenarios. Here's some more information on switch statements:
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
Welcome to the Stack Overflow community, make sure you use Google before you use Stack!
I am not sure what you want to do. But as per your approach it seems like you want to input a number through keyboard and want to check if it is a single digit number or not. If I am right then here we go.
public class Tests1 {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the number");
int number = sc.nextInt();
Tests1 obj1=new Tests1();
System.out.println(obj1.digit(number));
}
public boolean digit(int num) {
int count = 0;
while (num != 0) {
num = num / 10;
count++;
}
if (count == 1) {
return true;
}
return false;
}
}
My code check that the number is single digit or not. If it is a single digit number it return true else return false.

How to stop a do while loop using "0" in java

I just wanted to say first that I'm a beginner so I apologize for my (really) horrible code.
I'm creating a program where you input an int and print out the square root using a do while loop. And when you input "0" the program will stop.
How do you stop it?
public static void main(String[] args)
{
Scanner InputNum = new Scanner(System.in);
DecimalFormat formatTenths = new DecimalFormat("0.0");
do {
System.out.println("Please enter an integer.");
int sqroot = InputNum.nextInt();
double Finalsqroot = Math.sqrt(sqroot);
System.out.println("Your Square Root is: " + (formatTenths.format(Finalsqroot)));
} while (sqroot==0);
System.out.println("Closing...");
InputNum.close();
}
}
You need to test if the value entered was 0 (I would test less than or equal to zero, because the square root of a negative number is imaginary). If so, break the loop. Like,
int sqroot = InputNum.nextInt();
if (sqroot <= 0) {
break;
}
try this
public static void main(String[] args) {
Scanner InputNum = new Scanner(System.in);
DecimalFormat formatTenths = new DecimalFormat("0.0");
int sqroot = 0;
do {
System.out.println("Please enter an integer.");
sqroot = InputNum.nextInt();
double Finalsqroot = Math.sqrt(sqroot);
System.out.println("Your Square Root is: " + (formatTenths.format(Finalsqroot)));
} while (sqroot != 0);
System.out.println("Closing...");
InputNum.close();
}
I just initialize sqroot outside of your while and change == to !=
This academic exercise may demand use of a do/while loop, but if you're not constrained to using it, a for loop would also work:
public static void main(String[] args)
{
Scanner InputNum = new Scanner(System.in);
DecimalFormat formatTenths = new DecimalFormat("0.0");
System.out.println("Please enter an integer.");
for(int sqroot = InputNum.nextInt(); sqroot > 0; sqroot = InputNum.nextInt()) {
double Finalsqroot = Math.sqrt(sqroot);
System.out.println("Your Square Root is: " + (formatTenths.format(Finalsqroot)));
}
System.out.println("Closing...");
InputNum.close();
}
Your program as presented in the question has an intrinsic flaw: you ask for input and then immediately try and do something with it (calc the square root) without determining if it is suitable to use.
Switching to a for loop is one way this can be overcome, because it encourages a program flow of "ask for input", "check if input is acceptable", "use input", "repeat"
If you're constrained to using a do/while loop then you still need to follow this flow, which Elliott Frish addresses in his answer, recommending you add in the "check if input is acceptable" part as a dual purpose test of whether the input is <= 0.. Such values are not acceptable for a square root op, and you also want to end the program when you encounter them, so the test can be used to achieve both goals
Side trivia, for loops can be used pretty much exclusively:
for(;;) //same as while(true)
for(;test;) //same as while(test)
for(bool do = true; do; do = test) //same as do..while(test)
..though using while or do is probably more readable than using a for loop for the same job
Note, your while(sqroot==0) is a bug.. you don't want to continue looping while the user entered 0, you want to continue looping while they DIDN'T enter a 0...

Java Integer.parseInt() breaks program

I have a question to do in my Java class, and it asks me to write a program that takes in n numbers from the user and outputs the average of them. I know I could do it a much simpler way, just by asking the user to enter the amount of values (s)he needs to enter at the beginning, but I want to create the program so the user doesn't necessarily have to know the number of values at the beginning.
So for this, I create an array of 100 length (which hopefully covers the amount the user needs to enter) inside a for loop (rendering that 100 length array null after the loop, so the program doesn't become too memory heavy) and running a counter trough each iteration. Once the user enters stop, the loop ends, and the values entered into the 100 length array gets transferred to an array the size of the count.
Here is the code:
import java.util.*;
import java.lang.*;
public class main
{
public static void main(String args[])
{
Scanner input = new Scanner(System.in);
//Question 1
System.out.println("Enter your numbers. (Enter 'Stop' when you're done)");
int temp = 0;
String uInput = "";
char stopper;
int count = 0;
double total = 0;
int a = 0;
boolean inStop = true;
for (boolean stop = false; stop != true;)
{
int array [] = new int [100];
if (inStop == true)
{
System.out.println("point 5");
System.out.print("Input: ");
uInput = input.nextLine(); //reads user input
}
try //empty input repeater
{
System.out.println("point 1");
try //dealing with letters in string instead of numbers
{
System.out.println("point 2");
temp = Integer.parseInt(uInput); //converts string to int
array[count] = temp;
count++;
System.out.println(inStop);
if (inStop == false) //executes when stop has been reached
{
System.out.println("point 3");
int numberArray [] = new int [count]; //fills final array
for (int i = 0; i < count; i++)
{
numberArray[i] = array[i];
}
for (a = 0; a < numberArray.length; a++)
{
total = total + numberArray[a];
}
total = total / a;
stop = true; //ends parent loop
}
}
catch (NumberFormatException e) //catches letters in string and checks for stop
{
System.out.println("point 4");
stopper = uInput.charAt(0);
stopper = Character.toUpperCase(stopper);
if (stopper == 'S')
{
inStop = false;
System.out.println("point 6");
}
}
}
catch (StringIndexOutOfBoundsException e)
{
}
}
System.out.println("The average of the values entered is: " + total + ".");
}
}
The problem is, as you can see there are numerous numbered printouts that indicate (to me) where the program is at the moment. All runs fine, except for point 3. Point 3 for some reason doesn't execute whatsoever. No matter what I do. Now, the problem lies on line 34, temp = Integer.valueOf(uInput); //converts string to int
If I put in a print function directly after that line, that position doesn't print onto the screen. I believe there are no syntax or logic errors with that part, and so does my lecturer, however the code still doesn't execute and the program loops infinitely afterwards. Something is breaking either temp or uInput in that line and we cannot figure out what. I have compiled and ran the code through a different compiler to what I initially used and even tried in the Command Prompt with the same results (so it is not the IDE causing the issue).
Any insight we may have missed would be appreciated. Thanks.
p.s.: don't knock my lecturer, he didn't write the code, and it isn't that easily readable. He could easily know what the problem is, if not for any error in my explanations or his interpretations of how my program is meant to run.
I think that the reason you are having a problem identifying the issue is because of your code structure.
You have mixed the logic for informing the use, with the logic for reading the inputs, and calculating.
If your main method only deal with informing the user, and relies on another method to calculate the average,and another to read the user's input everything will be easier to read, follow and see that you are parsing "stop" as an int.
public static void main(String[] args) {
System.out.println("instructions");
int[] all = readUserInputs();
double ave = calculateAverage(all);
System.out.println("message " + ave);
}
private static double calculateAverage(int[] numbers) {
// I will leave it to you to fill this out
return yourValue;
}
private static String readUserInputs() {
Scanner input;// as above
int[] values; // is an array best? What about a List?
for (int i = 0; ; i++) {
String line = input.nextLine();
if ("stop".equals(line) {
break;
}
//try to parse and put into array/list
}
return values;
}
Hopefully you will find this easier to read and work with,I have left a few gaps for you to fill in.

Splitting a String and Parsing it into an Integer

I have some logic (java.lang.ArrayIndexOutOfBoundsException) error in this part of my code for some reason. I want the user to input anything and have it be split and parsed into an integer. If the user fails to do so ask them again. And if they enter something like "g5 3 76h 23" have the program accept it as 5 3. Or if i can have the program deny this until the user only enters two numbers between 0 and 9 separated by a space, that would be fine aswell. The user also has the option of enetering a "q" to quit.
However, everytime i run it, it appears as if nothing was split into a new array. and I get the error.
/**
* Prompts the user for input
*/
public void promptUser() {
// a Scanner object that uses System.in for input.
Scanner scan = new Scanner(System.in);
// a prompt for the user, asking them for input.
System.out.print("Pick a coordinate [row col] or press [q] to quit: ");
// Get input from the user, checking for errors. If the input is
// correct (e.g., two numbers that in bounds and have not
// already been clicked), then call the click method for desired
// coordinates. If the user wants to quit the game then make sure
// to update the boolean state variable and print out a message.
String input = scan.next();
String del = "[\\s,;\\n\\t]+"; // these are my delimiters
String[] token = input.split(del); // here i will save tokens
int val0 = 11, val1 = 11;
boolean tf = true;
while(tf)
{
if(token[0] == "q")
{
isRunning = false;
System.out.println("Thank you for playing");
}
else
{
try
{
val0 = Integer.parseInt(token[0], 10);
}
catch (NumberFormatException nfe)
{
// invalid data - set to impossible
val0 = 11;
}
try
{
val1 = Integer.parseInt(token[1], 10);
}
catch (NumberFormatException nfe)
{
// invalid data - set to impossible
val1 = 11;
}
}
if( !(((val0 >= 0) && (val0 < rows)) && ((val1 >= 0) && (val1 < cols))) )
{
System.out.println("Input Invalid, pick a coordinate [row col] or press [q] to quit: ");
input = scan.next();
for(int i=0;i<2;i++)
{
token = input.split(del);
}
}
else if(false) //atm
{
}
else
{
tf = false;
}
click(val0, val1);
} //while loop
} // promptUser
You need to validate the length of your returned token[] array, as it is possible that no "tokens" are returned. I.E., you shouldn't try to access token[0] and token[1] without first ensuring that they exist.
An example check:
if(token.length > 1)
From the Scanner documentation:
A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace.
You could change it to:
scan.useDelimiter(del); // If you want to split on more than just whitespace
while(scan.hasNext()) {
String input = scan.next();
if("q".equals(input)) {
System.out.println("Thank you for playing");
return;
}
// etc. Put in a list or array for use later.
}
Remember that Strings are objects so == only returns true if both strings are the same object, not if they have the same value. Use .equals for value comparison.

Categories

Resources