I've been given the task of making a factorial calculator that takes input from 9 to 16 using a while loop. The conditions are that if the user puts in an input that is not 9 to 16 or an int, it should loop back in the beginning and ask for input again.
My code looks like this:
Scanner myScanner;
int x = 1;
int factorial=1;
int input;
myScanner = new Scanner(System.in);
System.out.println("put in an int and i will show you its factorial");
while (true) {
input = myScanner.nextInt();
if (input<9 || input >16) {
System.out.println("please enter a valid int");
}
else{
break;
}
}
for (int i=input; i >0; i--) {
factorial *= i;
}
The problem is that this isn't really using a while loop to go back to the beginning of the code. I'm really just inputting a redundant statement to make it a while loop.
So I guess my question is, how can I make a while loop that goes back to the beginning of the loop if the wrong input is typed in?
an alternative is to use a boolean value such as
boolean validInput = false;
and loop until you have valid input. that way you won't try to calculate a value when users enter -1 in the other answer
Try doing it this way:
Scanner myScanner;
int x = 1;
int factorial=1;
int input = 0;
myScanner = new Scanner(System.in);
System.out.println("Put in an integer value between 9 and 16 and I will show you its factorial. Type -1 to exit.");
while (input != -1) {
//Try block for handling invalid string inputs
try {
input = myScanner.nextInt();
} catch (Exception e){
input = 0;
}
if (input<9 || input >16) {
System.out.println("please enter a valid int");
}
else {
for (int i=input; i >0; i--) {
factorial *= i;
//input = -1; //Optionally end here if that's how things are intended to function
}
System.out.println(factorial);
}
}
Initialize the input with a value (0). And inform the user if they type in a certain value (i.e. -1) the loop ends. Move your for loop in the else block and set the while condition as input != 1.
Alternatively, if you want the program to end if the user supplies a valid value, then in the else block, set the input value to -1 manually, or just break out of the loop using the break keyword.
Related
Scanner scanner = new Scanner(System.in);
int grade[] = new int[3];
for (int i = 0; i < grade.length; i++) {
System.out.println("Enter your test score:");
grade[i] = scanner.nextInt();
}
I've been trying to figure out how to make it so if the user input is below 0 or above 100 it will ask again. I'm very new to Java and this is the first language I'm learning. I would appreciate any pointers. Do I need to use a do-while loop instead of a for loop for this? Or do I implement an if statement into the for loop?
You can validate the input by putting an if block inside the for loop.
However, since your loop will only execute three times, you should change your increment condition only when user enters correct input or else not.
You also can use while loop here.
Here is some example code:
for (int i = 0; i < grade.length; i++)
{
System.out.println("Enter your test score:");
if(grade[i] < 0 || grade > 100)
{
i--;
continue;
}
grade[i] = scanner.nextInt();
}
The if block will check that if the input is outside boundaries, decrement i and restart the loop.
What I suggest is, instead of incrementing i in loop, you can increase the value in if condition. Like below,
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int grade[] = new int[3];
for (int i = 0; i < grade.length;) {
System.out.println("Enter your test score:");
int temp = scanner.nextInt();
if (temp >= 0 && temp <= 100) {
grade[i] = temp;
i++;
}else {
System.out.println("Please enter valid score");
}
}
scanner.close();
}
This basically gets a input value from user, if the value is greater or equal to 0 && lesser or equal to 100,then adds it to the Array and increments the loop count(array index value we can call it), else, prints message asking for valid input.
Instead of shoving the validation logic somewhere within the loop, you could also write a small utility method which neatly asks for valid input, and continues to do so until the user finally inputs something valid:
int promptInt(Scanner scanner, int min, int max, String errorMessage) {
while (true) {
int input = scanner.nextInt();
if (min <= input && input <= max) {
return input;
}
else {
System.out.println(errorMessage);
}
}
}
You could then simplify the loop:
int grade[] = new int[3];
for (int i = 0; i < grade.length; i++) {
System.out.println("Enter your test score:");
grade[i] = promptInt(0, 100, "Please enter a valid number");
}
I'm trying to handle a user input and allow for only floats to be entered. The number of floats that can be entered is unlimited, but if two consecutive non-floats are entered the program will end. When the program ends it will print the sum of all the numbers.
The problem is that whenever I run this it immediately runs through the while loop and increases the count to 2 and breaks the loop. You're only able to enter one non-float before it cancels out.
while(true){
try{
sum+= inRead.nextFloat();
}
catch (InputMismatchException e){
if (count == 2){
System.out.println(sum);
break;
}
else{
count+=1;
}
}
}
EDIT: As a few of you had pointed out that count should be initialized before the while loop
Scanner inRead = new Scanner(System.in);
float sum = 0;
int count = 0;
while(true){
try{
sum+= inRead.nextFloat();
}
catch (InputMismatchException e){
if (count == 2){
System.out.println(sum);
break;
}
else{
count+=1;
}
}
}
Try this:
Scanner inRead = null;
float sum = 0;
int count = 0;
while(true){
try{
inRead = new Scanner(System.in);
sum+= inRead.nextFloat();
if(count == 1) {
count = 0;
}
}
catch (InputMismatchException e){
if (count == 1){
System.out.println(sum);
break;
}
else{
inRead = null;
count+=1;
}
}
}
The counter increments 2 in your code because when you encounter an InputMismatchException in a nextFloat() method. the second nextFloat() you will encounter will not work because you need to create a new Scanner for that because it causes an error earlier in your loop, and I add if(count == 1) when you need to reset it to 0 so it can satisfy your problem to stop and add all when two consecutive non-float will be inputted.
You should initialize count to 0 before while loop starts and everything goes fine. If you have initialized count to 1 then, when non float number is entered then the count becomes 2 and next time if you enter non float number then the loop terminates.
Perhaps you reused the variable count from somewhere earlier in your code causing it to break early due to an incorrect value.
You should initialize count to 0 and only increment when a non-float number is entered.
Posting more of your code could help solve the problem.
The accepted answer is broken, as constructing additional Scanner instances may actually discard parts of the input. I would strongly suggest only ever using one object to read from System.in, since it's possible (and common) for a input-reader object like Scanner to buffer data internally from the source, and replacing that object with a new instance discards any input the first object already buffered.
It's also not necessary to get the behavior you want. Instead use .next() to skip the next token if it's not valid, and use .hasNextDouble() to determine if the next token is a valid double (rather than catching the InputMismatchException).
try (Scanner in = new Scanner(System.in)) {
double sum = 0;
boolean lastInputBad = false;
while (true) {
if (in.hasNextDouble()) {
sum += in.nextDouble();
lastInputBad = false;
} else if (lastInputBad) {
break; // break the loop on a subsequent bad input
} else {
in.next(); // skip first bad input
lastInputBad = true;
}
}
System.out.println("Sum of valid inputs: " + sum);
}
Note also that I used double, rather than float. There's essentially no reason to use float in modern code; just stick to double.
I am trying to validate my code by error checking. I want to make sure the integer people enter does not contain a letter or more.
Here is my code. I am supposed to solve this problem using a one dimensional array. I got the code working but I am having problems with adding the error checking in.
Any help would be appreciated. Thanks
public void getNumbers() {
Scanner keyboard = new Scanner(System.in);
int array[] = new int[5];
int count = 0;
int entered = 0;
int k = -1;
while (entered < array.length) {
System.out.print("Enter a number ");
int number = keyboard.nextInt();
if (10 <= number && number <= 100) {
boolean containsNumber = false;
entered++;
for (int i = 0; i < count; i++) {
if (number == array[i]) // i Or j
{
containsNumber = true;
}
}
if (!containsNumber) {
array[count] = number;
count++;
} else {
System.out.println(number + " has already been entered");
}
} else {
System.out.println("number must be between 10 and 100");
}
//what does %d do?
for (int j = 0; j < count; j++) {
System.out.printf("%d ", array[j]);
}
System.out.println();
}
}
}
I'm assuming that you would want your program to ask the user to re-enter a number if they do not input a number the first time. In this scenario you might want to try something along the lines of this:
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number: ");
while(!sc.hasNextInt()) {
//print some error statement
sc.nextLine();
}
int number = sc.nextInt();
System.out.println("Number is: " + number); // to show the value of number
// continue using number however you wish
Since hasNextInt() returns a boolean determining whether or not the input is an Integer, the program will never leave the while-loop until the program can confirm that the user has entered an integer.
keyboard.nextInt() will throw a InputMismatchException if you input a String.
If you want to check whether Scanner has an integer to read, you can use keyboard.hasNextInt().
Alternatively, you can read the input as
String s = keyboard.next() which will take the input as a String, and then use s.matches(".*\\d+.*") to detect whether or not it is an integer.
UPDATE: To answer questions -
keyboard.hasNextInt() will return a boolean. So for example, after System.out.print("Enter a number"), you could have an if statement checking to see if keyboard can receive numerical input, ie. if(keyboard.hasNextInt). If this is true, that means the user has entered numerical input, and you could continue with sayingint number = keyboard.nextInt(). If it is false, you would know that the user input is non-numerical.
What I am attempting to do is verify user input of an integer between 0-136, while also making sure that the input IS in fact an integer. I can't figure out a good way to do so, as using nextInt in the conditional consumes the int, and you can't compare hasNextInt to integers. Any help would be greatly appreciated!
Here is my code:
public static int retrieveYearsBack() {
Scanner input = new Scanner(System.in);
//Retrieve yearsBack
System.out.println("How many years back would you like to search? (Enter only positive whole numbers less than 136)");
while (!input.hasNextInt([0-136]) {
System.out.println("Invalid entry. Please enter a positive whole number less than 136 only.");
input.next();
}
return input.nextInt();
}
I have also tried:
int myYears = -1;
int tempValue = 0;
while (!input.hasNextInt() || (myYears < 0 || myYears > 136)) {
if (input.hasNextInt())
tempValue = input.nextInt();
if (tempValue > 0 && tempValue < 136)
myYears = tempValue;
else {
System.out.println("Invalid entry. Please enter a positive whole number less than 136 only.");
input.next();
}
}
This try gets stuck in an infinite loop.
I believe that you do need the input.next() call despite what Vivin says. If you can't read an integer from the next line of stdin then you will end up in an infinite loop. Furthermore, you should handle the case where you run out of lines of stdin to process, which can happen where your application's input is from a pipe instead of an interactive session.
In a more verbose style, this might look something like:
public static int retrieveYearsBack() throws Exception
{
Scanner input = new Scanner(System.in);
while (input.hasNext()) {
if (input.hasNextInt()) {
int years = input.nextInt();
if (0 <= years && years <= 136) {
return years;
}
} else {
input.next();
}
System.out.println("Invalid entry. Please enter a positive whole number less than 136.");
}
throw new Exception("Standard in was closed whilst awaiting a valid input from the user.");
}
I am trying to find the smallest number in the list from user input. I need to ask the user how many numbers are going to be in the list (and only accept positive numbers and no letters) and then ask them what the numbers are in the list (accepting only numbers). How can I check for this and keep looping until the numbers are valid?
public class SmallestInt {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// Initialize a Scanner to read input from the command line
Scanner input = new Scanner(System. in );
int totalIntegers = 1;
int num = 0;
int smallest = 0;
boolean inputValid = false;
/* Prompt the user and validate their input to ensure they've entered a positive (greater than zero) integer. Discard/ignore any other data.
*/
while (!inputValid)
{
System.out.print("How many integers shall we compare? (Enter a positive integer): ");
try {
totalIntegers = input.nextInt();
inputValid = true;
} catch (NumberFormatException e) {
System.out.println("Invalid input!");
}
/* Read in the candidates for smallest integer
* Validate this input as well, this time ensuring that the user has provided a valid int (any int will do at this point) and discarding any other data
*/
for (int ii = 1; ii <= totalIntegers; ii++) {
// Prompt
System.out.print("Enter value " + ii + ": ");
num = input.nextInt();
if (ii == 1) smallest = num;
else if (num < smallest) smallest = num;
}
// display smallest int
System.out.println("The smallest number entered was: " + smallest);
}
}
}
Let's come up with an sample for you so you can follow as your blueprint
first, I chose do while loop because you need to ask this question at least once.
he syntax of a do...while loop is:
do
{
//Statements
}while(Boolean_expression);
Notice that the Boolean expression appears at the end of the loop, so
the statements in the loop execute once before the Boolean is tested.
If the Boolean expression is true, the flow of control jumps back up
to do, and the statements in the loop execute again. This process
repeats until the Boolean expression is false.
Next, you need to see how you can staisfy the boolean_experssion when the input is right, so you can stop looping or if it is wrong, you keep asking the question.
The way that I really like is to use sentinel value because using break keyword really scares me.
In programming, a special value that is used to terminate a loop. The
sentinel value typically is chosen so as to not be a legitimate data
value that the loop will encounter and attempt to perform with. For
example, in a loop algorithm that computes non-negative integers, the
value "-1" can be set as the sentinel value as the computation will
never encounter that value as a legitimate processing output.
so when the input is right you change the value of i, so you can stop the looping or otherwise, showing the message and asking the question again and again till the use hits the right answer.
Code:
int i = 0;
Scanner input = new Scanner(System.in);
while (i == 0) {
System.out.println("Enter number zero plz");
int result = input.nextInt();
if(result == 0 ){
System.out.println("I entered right number");
i = 1;
} else
System.out.println("you entered the wrong number \nplz try again");
}
output:
Since this is clearly a homework / learning exercise, I won't give you code. You will learn more if you do the actual coding for yourself.
Once you have fixed the problem with the loop nesting ...
There are three problems with this code:
while (!inputValid) {
System.out.print("How many integers? (Enter a positive integer): ");
try {
totalIntegers = input.nextInt();
inputValid = true;
} catch (NumberFormatException e) {
System.out.println("Invalid input!");
}
}
First problem is that you are catching the wrong exception. Read the javadoc.
The second problem is that if nextInt fails (due to a problem parsing the integer) it puts the scanner's input cursor back to where it was before the call. And when you call it again (in the next loop iteration) it will attempt to read same "bad" number again, and again, and again, ...
You have to tell the scanner to skip over the invalid line of input so that it can read the user's next attempt.
The third problem is that you don't check that the number you just read is positive!!
Final hint: consider using while (true) and a conditional break, instead of while (condition). I think it gives a more elegant solution.
#Kick Buttowski's solution deals with the bad input skipping by creating a new Scanner on each loop iteration. Apparently it works ... but I have some doubts1 that you can rely on this always working. IMO a better solution would be to use one Scanner throughout, and use a nextLine() call to read and discard the characters up to and including the end of line.
1 - My main concern is that when you leak a Scanner that it might (in some implementations) close the underlying input stream in a finalizer. If that actually happened, then the application would stop accepting input. The current implementation does not do this, but this is not clearly specified (AFAIK).
Your while loop really isn't doing anything for you in terms of stopping the user from advancing. You are able to hit the for loop because it is inside you while loop. Change your while loop and for loop so that the for loop is outside the while loop.
while (!inputValid)
{
System.out.print("How many integers shall we compare? (Enter a positive integer): ");
try {
totalIntegers = input.nextInt();
inputValid = true;
} catch (NumberFormatException e) {
System.out.println("Invalid input!");
}
} // End while //
/* Read in the candidates for smallest integer
* Validate this input as well, this time ensuring that the user has provided a valid int (any int will do at this point) and discarding any other data
*/
for (int ii = 1; ii <= totalIntegers; ii++) {
// Prompt
System.out.print("Enter value " + ii + ": ");
num = input.nextInt();
if (ii == 1) smallest = num;
else if (num < smallest) smallest = num;
} // End for //