Stuck inside while loop - java

I'm trying to print the value of z as output but My code doesn't finish execution..it reaches the line "here" but never reachs the last line "z is ".
i'm guessing s = sc.nextInt(); is the problem.
public class Solution {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int x = 0;
int y = 0;
int z = 0;
int u = 0;
int n = sc.nextInt();
int s = sc.nextInt();
while(sc.hasNextInt()) {
if(s != -1){
y = s;
if(sc.hasNextInt()){
s = sc.nextInt();
}
}
while(s == -1){
x++;
System.out.println("s is "+s);
z = Math.abs(y - x) + u;
System.out.println("s is "+s);
System.out.println("x is " + x+ " y is "+ y+" z is "+z);
if(sc.hasNextInt()){
s = sc.nextInt();
System.out.println("s33 is "+s);
}
}
if(z != 0){
u = z;
}
x = 0;
y = 0;
System.out.println("here");
}
System.out.println("z is" +z);
}
}
Thanks.

Its not going in infinite loop but instead you already have two values stored in Scanner which you are checking with hasNextInt(). Hence its always true and waits for next input to check. If you go with entering Int values it will be in same while loop. Enter non-integer like String to go out of while loop and your program will end.
Actually You are waiting for input in both while loops and hence its waiting for your input.

Problem
You are using a Scanner on the system input stream System.in. That means sc.hasNextInt() tries to get the next value from the underlying stream, which is System.in. However, this stream will just prompt you for new input and return it to the Scanner. Once the Scanner receives a newline character, it checks, if the sequence before is an int or not. In case you only hit enter, the sequence is empty, hence ignored. It is not the loop that is indefinitely executed if you hit enter repeatedly, your code is stuck at sc.hasNextInt(), which gets no new token (because of the empty sequence), and asks the underlying stream again and again.
However, if you enter anything but an int, like 0.2 or abc... the Scanner will return false, as the sequence is not empty and not an int.
Solution
If you want to keep your code as it is and you want that hasNextInt() returns false when you hit enter (only newline), you can wrap your Scanner in this wrapper:
import java.util.Scanner;
public class ScannerWrapper {
private Scanner scanner;
private Integer current;
public ScannerWrapper(Scanner scanner) {
this.scanner = scanner;
}
public boolean hasNextInt() {
// Current is not null, if method is called multiple
// times, the value was checked already, it is an integer
if (current != null) {
return true;
} else {
// Reads line including newline character
String nextLine = scanner.nextLine();
try {
// Try to covert the input to an integer
current = Integer.parseInt(nextLine);
return true;
} catch (NumberFormatException e) {
// Input is not an integer
return false;
}
}
}
public int nextInt() {
// Used the already checked value or request new input
if (current != null) {
int next = current;
current = null;
return next;
} else {
int next = scanner.nextInt();
// Consume the newline character
scanner.nextLine();
return next;
}
}
}
This class reads complete lines and converts them into int, if possible. As you cannot push back the last token you have read with a Scanner, this class stores it temporarily, so multiple calls to hasNextInt() do not skip values. In your method just add:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
ScannerWrapper sc = new ScannerWrapper(scanner);
int x = 0;
// Rest of your code...
}

Related

Line by line input evaluation with operators and how to store the changing value until user types "."

I'm trying to make a program that evaluates a mathematic equation that's written one character or value per line at a time. The user will enter alternating numbers and operators, line by line, terminating with a ‘.’. That means I'm not trying to evaluate from a single string (and assume input will always alternate between number and operator).
I don't know how to make it so that it keeps taking input until the user types ".'
I also am not sure how to keep the value continuously changing as the user types the formula and how to store that.
Sample input:
1
+
6
-
3
.
The solution to your equation is: 4
import java.util.Scanner;
class Evaluator {
static int add (int a, int b)
{
return a + b;
}
static int multiply (int a, int b)
{
return a * b;
}
static int divide (int a, int b)
{
return a / b;
}
static int subtract (int a, int b)
{
return a - b;
}
static int modulus (int a, int b)
{
return a % b;
}
public static void main(String [] args)
{
Scanner input = new Scanner (System.in);
int a,b,c;
System.out.println("Enter the equation:");
a = input.nextInt();
String c = input.next();
b = input.nextInt();
if (c.contains("+")) {
int result = add (a,b);
}
else if (c.contains("*")) {
int result = multiply (a,b);
}
else if (c.contains("/")) {
int result = divide (a,b);
}
else if (c.contains("-")) {
int result = subtract (a,b);
}
else if (c.contains("%")) {
int result = modulus (a,b);
}
else if (c.contains(".")) {
break;
}
System.out.print("The solution to your equation is: " + result);
}
}
Your code is very close, in that you use Scanner next() and nextInt() in the correct order (to match the input rules). Here a while(true) loop is added around the pair of inputs; either a user enter a '.' and the loop breaks, or the user enters an operator followed by the next number. The result is kept up to date by using it repeatedly in the various math operators.
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int b, result;
System.out.println("Enter the equation:");
result = input.nextInt();
while (true) {
String c = input.next();
if (c.contains(".")) {
break;
}
b = input.nextInt();
if (c.contains("+")) {
result = add(result, b);
} else if (c.contains("*")) {
result = multiply(result, b);
} else if (c.contains("/")) {
result = divide(result, b);
} else if (c.contains("-")) {
result = subtract(result, b);
} else if (c.contains("%")) {
result = modulus(result, b);
}
}
input.close();
System.out.print("The solution to your equation is: " + result);
}
Here is a simple while loop you can use to get input from the user. I have a check if it's a digit or something else. You can use this skeleton to grab input from the user and exit when someone presses "."
Scanner input = new Scanner (System.in);
int a,b,currentTotal = 0;
String inputFromUser = "nothing";
while(!inputFromUser.equals("."))
{
inputFromUser = input.nextLine(); //grab line by line
if(inputFromUser.matches("\\d+")){
//parse the number and set it to a value like a...
System.out.println("You entered a number: " + inputFromUser);
}
else if(!inputFromUser.equals(".")){
//check if you have value and try to apply your number to your current total
System.out.println("You entered something other than a number: " + inputFromUser);
}
}
If the user enters a number, set a variable to that number, perhaps a
If the user enters something other than a number and not a period then check if the input is a valid operation with your provided logic and apply it like operatorMethod(a, currentTotal)

Asks user to enter values until an integer is entered

I am a noob in programming.
I wanted to write code for a prog which asks user to enter value until an integer is entered.
public class JavaApplication34 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int flag = 0;
while(flag == 0) {
int x = 0;
System.out.println("Enter an integer");
try {
x = sc.nextInt();
flag = 1;
} catch(Exception e) {
System.out.println("error");
}
System.out.println("Value "+ x);
}
}
}
I think the code is correct and it should ask me to enter the value again if i have entered anything other than an integer.
But when i run it , and say i enter xyz
it iterates infinite time without asking me to enter the value.
test run :
Enter an integer
xyz
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
When a scanner throws an InputMismatchException, the scanner will not
pass the token that caused the exception.
Hence sc.nextInt() reads the same token again and throws the same exception again.
...
...
...
catch(Exception e){
System.out.println("error");
sc.next(); // <---- insert this to consume the invalid token
}
You can change your logic as shown below :
int flag = 0;
int x = 0;
String str="";
while (flag == 0) {
System.out.println("Enter an integer");
try {
str = sc.next();
x = Integer.parseInt(str);
flag = 1;
} catch (Exception e) {
System.out.println("Value " + str);
}
}
Here we have first read the input from Scanner and then we are trying to parse it as int, if the input is not an integer value then it will throw exception. In case of exception we are printing what user has enter. When user enters an integer then it will parsed successfully and value of flag will update to 1 and it will cause loop to exit.
In the error case, you need to clear out the string you've entered (for instance, via nextLine). Since it couldn't be returned by nextInt, it's still pending in the scanner. You also want to move your line outputting the value into the try, since you don't want to do it when you have an error.
Something along these lines:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int flag = 0;
while(flag == 0)
{
int x = 0;
System.out.println("Enter an integer");
try
{
x = sc.nextInt();
flag = 1;
System.out.println("Value "+ x);
}
catch (Exception e){
System.out.println("error");
if (sc.hasNextLine()) { // Probably unnecessary
sc.nextLine();
}
}
}
}
Side note: Java has boolean, there's no need to use int for flags. So:
boolean flag = false;
and
while (!flag) {
and
flag = true; // When you get a value
The answers to this question might help you
It makes use of Scanners .hasNextInt() function!

How would i do input validation?

Tells the user if the number entered is even or even. I need help with the input validation. The validation i need do is that the user cannot entered anything but a number. Trying to do the validation without the try and catch method.
import java.util.Scanner;
public class oddoreven {
public static void main (String [] args) {
Scanner input = new Scanner (System.in);
//declaractions
int num;
//while loop
do{
System.out.println("PLease enter a number to see whether it is even or odd. To end tyype in -99.");
num = input.nextInt();
// input valid
}while(num != -99); // loop ends
// begins the method
public static void is_odd_or_even_number(int number){
int rem = number%2;
\
You can call Scanner.hasNextInt() to determine if the next input is an int (and consume anything else). Also, you might make an infinite loop and break when the input is -99 (or 99, your code tests for 99 but your prompt says -99). Finally, you should call your method. Something like,
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int num;
do {
System.out.println("Please enter a number to see whether it is "
+ "even or odd. To end type in -99.");
if (input.hasNextInt()) {
num = input.nextInt();
if (num != -99) { // <-- directions say -99.
is_odd_or_even_number(num);
} else {
break;
}
} else {
System.out.printf("%s is not a valid int.%n", input.nextLine());
}
} while (true);
}
You can use Scanner.nextLine() to get a string input. Then loop through the characters to make sure they are all digits. (assuming non-negative integers only)
string rawInput = input.nextLine();
boolean validInput = true;
for (char c : rawInput) {
if (!Character.isDigit(c)) {
validInput = false;
break;
}
}
if (validInput) {
int num == Integer.parseInt(rawInput);
// proceed as normal
}
else {
// invalid input, print out error message
}
You can use regex to check whether all the characters of string entered by user are digits or not,
num.matches("[0-9]+") // return true if all characters are digits
or
num.matches("^[0-9]*$") // return true if all characters are digits
but before that change your num = input.nextint() to num = nextLine() and make num as String. if you dont do this there is no need of validating user input as you are requiring.

java exception handling - divide by zero and divide by text method

I've been doing java for 4 months, so I'm still an amateur. Just trying to get some hwk done. Can't seem to find the right tips for getting my denominator to function well by rejecting text data and zero while keeping in a loop with error messages. Another issue is the fact my quotient is 0.0 no matter what my numerator / denominator is. Lots of problems, any advice is appreciated. Directions are as follows:
--This program takes user input for a (int) numerator and
(int) denominator then computes and displays the (double) quotient.
--If the user enters text instead of number for the numerator, display an error message explaining the issue and keep user in a loop until the correct data is entered.
--If the user enters text or a zero instead of a number for the denominator, display an error message explaining the issue and keep user in a loop until the correct data is entered.
--Messages should be descriptive with respect to the issue.
public static void main(String[] args) throws Exception {
Scanner console = new Scanner(System.in);
int n1 = 0; //number 1
int n2 = 1; //number 2..
double r = (double) n1 / n2; //quotient
String n1Str = "Please enter a real number for the numerator";
String n2Str = "Please enter a real number greater than zero for the denominator";
String errMsg = "Please enter a real number.";
String notZero = "Denominator cannot equal zero."; // not all string msgs are used, just there in case i need them.
try {
n1 = getInteger(n1Str); // validates against alphabet
if (hasNextInt()) { // working
n1 = console.nextInt();
}
} catch (InputMismatchException ime) {
}
try {
n2 = getInteger2(n2Str); // trying to validate against alphabet & zero
if (hasNextInt()) { // not working though...
n2 = console.nextInt();
}
} catch (InputMismatchException ime) {
}
System.out.println("Fraction result is " + r);
}
public static int getInteger(String message) {
Scanner console = new Scanner(System.in);
int count = 0;
boolean isValidInteger = false;
do {
System.out.println(message);
if (console.hasNextInt()) {
isValidInteger = true;
count = console.nextInt();
} else {
console.nextLine();
}
} while (!isValidInteger);
return count;
}
public static int getInteger2(String message) {
Scanner console = new Scanner(System.in);
int count = 0;
boolean isValidInteger = false;
do {
System.out.println(message);
if (console.nextInt() != 0 || console.hasNextInt()) { // validates against zero but
isValidInteger = true; // can't get it to validate against text.
count = console.nextInt(); //tried switching statements and using && but get thrown into endless loop
}
} while (!isValidInteger);
return count;
}
private static boolean hasNextInt() {
return false;
}
}
You have lots of issues with your code.
For starters, you should have only one Scanner, that would exist throughout the lifespan of your application. There's no need to instantiate multiple scanners.
public class SomeClass {
private static Scanner console;
public static void main(String[] args) throws Exception {
console = new Scanner(System.in);
(...)
console.close();
}
}
Now lets look into your problematic getInteger2 method.
You should simple validate, as you do on your getIntegermethod, if the input is an integer. If it is, you process it; otherwise, you skip it using next() (not nextLine()) since you want to jump over the next complete token from this scanner.
public static int getInteger2(String message) {
int count = -1;
boolean isValidInteger = false;
do {
System.out.println(message);
if (console.hasNextInt()) {
count = console.nextInt();
if (count != 0) {
isValidInteger = true;
} else {
System.out.println("Denominator cannot equal zero.");
}
} else {
console.next();
}
} while (!isValidInteger);
return count;
}
Finally, your quotient is always being printed 0.0 since you're not updating its value before outputting it:
r = (double) n1 / n2;
System.out.println("Fraction result is " + r);
The fact that your quotient "r" is always 0.0 is because you initialize n1 to be 0 and n2=1; You should just declare the variables and initialize them down in your code; i.e when you want to get the values from the user.
It seems that you have two "main" problems in your code/logic...
Problem 1) You are not calculating r (your quotient) after you get the inputs.
So the lines:
} catch (InputMismatchException ime) {
}
System.out.println("Fraction result is " + r);
could be changed to something like:
} catch (InputMismatchException ime) {
}
r = (double) n1 / n2; //calculate the quotient
System.out.println("Fraction result is " + r);
Problem 2)
Your code:
do {
System.out.println(message);
if (console.nextInt() != 0 || console.hasNextInt()) { // validates against zero but
isValidInteger = true; // can't get it to validate against text.
count = console.nextInt(); //tried switching statements and using && but get thrown into endless loop
}
} while (!isValidInteger);
return count;
could be changed to something like this, if you don't want to change too much in your code:
do {
System.out.println(message);
try {
if ((count = console.nextInt()) != 0) {
isValidInteger = true;
}
} catch (InputMismatchException ime) {
return getInteger2(message);
}
} while (!isValidInteger);
return count;
so that only if the input in console is an int you read it with nextInt() and store it in count. In your code you would read the int with nextInt() and if it is an int you read it again with nextInt(), which causes the user to write in 2 ints as well as your issue that you read the int before checking that it is an int which causes the InputMismatchException to be thrown. In the code I sent you, if the read number is an int AND not 0 then it is returned, if it is 0 your loop runs again and if it isn't an int at all the the method is simply called again (see Recursion).
I hope this helps you understand the issues.
The best way, however, would probbaly be do redesign your code a bit.

Checking if an input is an Integer using exceptions - Java

My method must request input from the user, check if it is an integer, and if it is return that integer. I attempted this using a try catch and the InputMismatchException.
I am running into an issue when it loops, if I input a non integer, it continuously spits out "Invalid input" "Enter an integer: " instead of actually asking for one.
public int getInteger(){
Scanner i = new Scanner(System.in);
int value = 0;
for(boolean test = false; test == false;){
try{
System.out.println("Enter an integer: ");
value = i.nextInt();
test = true;
return value;
}
catch(InputMismatchException e){System.out.println("Invalid input");}
}
return value;
}
You need a i.nextLine(); at the end of the loop.
catch(InputMismatchException e){System.out.println("Invalid input");}
i.nextLine();
}
What that does is reads the new line character, left unread by i.nextInt(), from the input stream. It's also the reason your i.nextInt() keeps tripping on the subsequent calls.
I suggest you call hasNextInt() before nextInt() instead of trying to catch the Exception. Something like,
public int getInteger() {
Scanner scan = new Scanner(System.in);
while (scan.hasNextLine()) {
if (scan.hasNextInt()) {
return scan.nextInt();
} else {
System.out.printf("%s is not an int%n", scan.nextLine());
}
}
return -1;
}

Categories

Resources