What does .next(); do in this case? - java

This is the code which expects the integer input. If the input is integer the loop ends else the input is asked again. But if I do not include sc.next(); it will go into infinite loop when non integer value is given. Here is the main function:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
boolean status = false;
while (!status) {
status = sc.hasNextInt();
if (status){
System.out.println("Number of people recorded");
} else {
System.out.println("Enter a valid integer number.");
}
sc.next();
}
}

You don't need status as a separate variable. You merely need to consume the token that isn't an int while you wait for an int. Like,
Scanner sc = new Scanner(System.in);
while (true) {
if (sc.hasNextInt()) {
System.out.println("Number of people recorded " + sc.nextInt());
break; // <-- end the loop
} else {
System.out.println("Enter a valid integer number.");
sc.next(); // <-- it's not an int, but consume whatever it is
}
}

sc.hasNextInt() tells you if the input is an integer or not. If it is, then the loop exits. If it isn't, then the loop continues. It continues infinitely because you never read what the input actually was, since sc.hasNextInt() is false. Including a sc.next() will actually get the input, pausing, and therefore not infinitely continuing the loop.

Related

Repeatedly check whether integer input has leading zeroes

I need the user to enter an integer input, check whether it starts by 0 and tell the user to enter another integer if that is the case
I tried parsing the integer input to a string, that works but only once. The string cannot be edited when program loops
I think the solution should not at all involve strings because i need the program to loop and check over and over until the input is valid (ie has no leading zeroes)
Splitting each digit of the int into an array does not work also because the ways i found pass by string.
public static void main(String[] args){
Scanner key = new Scanner(System.in);
int in= 0;
boolean looper=true;
while (looper == true) {
System.out.println("Enter an integer");
in = key.nextInt();
/* check whether in has any leading zeroes, example of
wrong input: 09999, 0099*/
if (/*in has no leading zeroes*/)
looper = false;
}
key.close();
}
Maybe another answer would be to have a method that creates a brand new string every time the program loops, so maybe like a recursion that automatically creates strings, not sure if that's even a thing though.
You can make it cleaner by using a do-while loop instead of while(true). Note that an integer starting with 0 is an octal number e.g.
public class Main {
public static void main(String[] args) {
int x = 06;
System.out.println(x);
// x = 09; // Compilation error - out of range
}
}
Thus, 06 is a valid integer. For your requirement, you can input to a String variable and prompt the user to again if it starts with a zero. If the input does not start with a zero, try parsing it to an int and process it if it succeeds; otherwise, loopback e.g.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner key = new Scanner(System.in);
String input = "";
int in = 0;
boolean valid = true;
do {
System.out.print("Enter an integer: ");
input = key.nextLine();
if (input.startsWith("0")) {
System.out.println("Invalid input");
valid = false;
} else {
try {
in = Integer.parseInt(input);
System.out.println("You entered " + in);
// ... process it
valid = true;
} catch (NumberFormatException e) {
System.out.println("Invalid input");
valid = false;
}
}
} while (!valid);
}
}
A sample run:
Enter an integer: 09999
Invalid input
Enter an integer: xyz
Invalid input
Enter an integer: 123
You entered 123
As an aside, never close a Scanner(System.in) because it also closes System.in and there is no way to open it without rebooting the JVM.

Exiting from while loop not working in java

I am new to java programming.I want to calculate the sum and want to exit the program if user enters "N" and again loop if user enters "Y".But,it is not getting me out of loop even I enter "N".
public class Program {
public static void main(String[] args) {
boolean a=true;
while (a) {
System.out.println("enter a number");
Scanner c=new Scanner(System.in);
int d=c.nextInt();
System.out.println("enter a number2");
Scanner ce=new Scanner(System.in);
int df=ce.nextInt();
int kk=d+df;
System.out.println("total sum is"+kk);
System.out.println("do you want to continue(y/n)?");
Scanner zz=new Scanner(System.in);
boolean kkw=zz.hasNext();
if(kkw) {
a=true;
}
else {
a=false;
System.exit(0);
}
}
}
I didnt know where I made the mistake? Is there any other way?
First of all, your a variable is true if scanner.hasNext() is true, leading to a being true with every input, including "N" which means, your while loop will keep on going until there are no more inputs.
Second of all, you could optimize your code the next way:
I suggest getting rid of a and kkw to make your code cleaner and shorter.
Use only one Scanner and define it outside of the loop. You don't need more than one Scanner for the same input. Also, initializing a Scanner with every loop is resource-consuming.
Use meaningful variable names. Programming should not only be efficient, but also easy to read. In this tiny code it's a minor issue but imagine having an entire program and, instead of adding features and bug-fixing, you had to search for the meaning of every variable.
Here's an optimized and working version of your code:
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("Enter a number");
int input1 = scanner.nextInt();
scanner.nextLine(); // nextInt() doesn't move to the next line
System.out.println("Enter a second number:");
int input2 = scanner.nextInt();
scanner.nextLine();
System.out.println("Total sum is " + (input1 + input2)); /* Important to
surround the sum with brackets in order to tell the compiler that
input1 + input2 is a calculation and not an appending of
"Total sum is "*/
System.out.println("Do you want to continue? (Y/N)");
if (scanner.hasNext() && scanner.nextLine().equalsIgnoreCase("n"))
break;
}
scanner.close();
try (Scanner in = new Scanner(System.in)) {
boolean done = false;
while (!done) {
System.out.println("enter first number");
int d = in.nextInt();
System.out.println("enter second number");
int df = in.nextInt();
int kk = d + df;
System.out.println(String.format("total sum is %d", kk));
System.out.println("do you want to continue(y/n)?");
String cont = in.next();
done = cont.equalsIgnoreCase("n");
}
} catch(Exception e) {
e.printStackTrace();
}

Why is this Scanner assigning null to a variable?

For a college assessment I'm having to use a Scanner called sc with a class-level scope, and the entirety of the program has to be contained in a single class. The main method calls a menu() method, which uses the Scanner and a for loop to call one of two methods in response to user input.
One of the two methods uses the Scanner to calculate the factorial of an input integer. Once the method is executed, the for loop in menu() continues. To avoid an InputMismatchException due to the user entering a float, I used try/catch. However when the program returns back to the menu() for loop the Scanner causes an InputMismatchException when assigning to choice. How can I get Scanner to prompt the user for input again? Apologies if I'm missing something obvious, this is the first programming language I've ever learned. This should be the stripped down compilable code:
package summativeassessment;
import java.util.InputMismatchException;
import java.util.Scanner;
public class SummativeAssessment {
private static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
menu();
}
public static void menu(){
String fName;
String sName;
System.out.print("Enter your first name: ");
fName = sc.next();
System.out.print("Enter your last name: ");
sName = sc.next();
try{
for(int choice = 1; choice!=0;){
System.out.print("Option 1 to generate username. Option 2 to calculate factorial. Press 0 to quit: ");
choice = sc.nextInt();
switch(choice){
case 2:
System.out.println(fName+" "+sName+", you have selected option 2");
numberFactorial();
break;
case 0:
break;
default:
System.out.println("Invalid option. Please try again.");
}
}
} catch(InputMismatchException ex){
String msg = ex.getMessage();
System.out.println(msg);
}
}
public static void numberFactorial(){
System.out.print("Enter a number: ");
try{
int numIn = sc.nextInt();
long result = numIn;
if(numIn>0){
for(int factor = 1; factor<numIn; factor++){
result *= factor;
if(factor==numIn-1){
System.out.println("The factorial is "+result);
}
}
}
else{
System.out.println("Enter a positive integer greater than 0");
}
}
catch(InputMismatchException ex){
System.out.println("Input invalid");
}
}
}
I debugged your code and got this result:
If you enter a float as input you trigger the InputMismatchException but there is still something in your buffer. So the next time sc.nextInt() is called, it won't wait until you input a value because something is in the buffer already, so it takes the next value out of the buffer and tries to interpret is as an integer. However, it fails to do so, because it is not an integer, so an InputMismatchException is raised again and caught in your menu's catch, now leading to the exit of the program.
The solution is to draw whatever is left in the buffer after the exception was raised the first time.
So the working code will contain a buffer clearing sc.next() inside the exception:
public static void numberFactorial(){
System.out.print("Enter a number: ");
try{
int numIn = sc.nextInt();
long result = numIn;
if(numIn>0){
for(int factor = 1; factor<numIn; factor++){
result *= factor;
if(factor==numIn-1){
System.out.println("The factorial is "+result);
}
}
}
else{
System.out.println("Enter a positive integer greater than 0");
}
}
catch(InputMismatchException ex){
System.out.println("Input invalid");
sc.next();
}
}

Checking the user input (scanner) before assigning to an int variable

int i;
Scanner scan = new Scanner(System.in) {
i = scan.nextInt();
}
What I want to do is to catch the error in scanner when a user inputs a character instead of an integer. I tried the code below but ends up calling for another user input (bec. of calling another scan.nextInt() in assigning value to i after validating the first scan.nextInt() of numeric only):
int i;
Scanner scan = new Scanner(System.in) {
while (scan.hasNextInt()){
i = scan.nextInt();
} else {
System.out.println("Invalid input!");
}
}
Your logic seems a bit off, you have to consume an input if it isn't valid. Also, your anonymous block seems very odd. I think you wanted something like
int i = -1; // <-- give it a default value.
Scanner scan = new Scanner(System.in);
while (scan.hasNext()) { // <-- check for any input.
if (scan.hasNextInt()) { // <-- check if it is an int.
i = scan.nextInt(); // <-- get the int.
break; // <-- end the loop.
} else {
// Read the non int.
System.out.println("Invalid input! " + scan.next());
}
}

How to tell my if-statement to only accept integers?

I want my program to tell the user that if (s)he enters a non-integer he should try again, instead of just terminating the whole main method like it does now. Pseudo code of problem part:
int integer = input.nextInt();
If (user types in a non-integer) {
("you have entered a false value, please retry");
then let's user enter int value
else {
assign nextint() to integer and continue
}
You can use a while loop to re-execute that portion of code until the user enters a proper integer value.
do {
input = read user input
} while(input is not an integer)
It seems you are using a Scanner, so you could use the hasNextInt method:
while (!input.hasNextInt()) {
let user know that you are unhappy
input.next(); //consume the non integer entry
}
//once here, you know that you have an int, so read it
int number = input.nextInt();
This is assuming that you are worried about the user entering in something other than an integer on input:
public static void main(String[] args) {
Integer integer = 0;
Scanner sc = new Scanner(System.in);
System.out.println("Enter an integer:");
String line = sc.next();
integer = tryParse(line);
while(integer == null){
System.out.print("The input format was incorrect, enter again:");
integer = tryParse(sc.next());
}
int value = integer.intValue();
}
public static Integer tryParse(String text){
try{
return new Integer(text);
} catch
(NumberFormatException e){
return null;
}
}

Categories