ending a programme through system.exit(0) in java - java

This is a continuation of a previous question to which i was unable to get an answer. The problem is when i try end the program using the System.exit(0) method with a switch statement and a "End" keyword and case, the code no longer runs as it should, only every second integer input is now read by the computer.
Here is my method that is no longer working:
public static int[] ourGuess() {
int[] guessed = new int[4];
Scanner scan = new Scanner(System.in);
System.out.println("Take your guess:");
switch (scan.nextLine()) {
case "End":
System.exit(0);
break;
}
guess = scan.nextInt();
int mod = 10;
int div = 1;
for (int i = 3; i >= 0; i--) {
int num = (guess % mod) / div;
guessed[i] = num;
div = div * 10;
mod = mod * 10;
}
return guessed;
}
The class is a java implementation of the mastermind game. Thanks for all the help!

You're reading two values from the Scanner.
First you read a value with scan.nextLine(), then you discard that value and read another with scan.nextInt().
You need to save the value read and reuse it:
final String line = scan.nextLine();
if(line.equals("End")) {
return guessed;
}
final int guessed = Integer.parseInt(line);
You also shouldn't call System.exit.

First of all, you should not use a switch statement for one case. Also, if the line read is not "End" but an int, you are skipping that one. Try:
String next = scan.nextLine();
if(next.equalsIgnoreCase("End")) System.exit(0);
Then check to see if next is the actual int that was guessed, otherwise read the next int.

By calling nextLine() and nextInt(), you are reading two things from the stream. Instead, cache the value of the nextLine():
String line = scan.nextLine();
switch (line) { ...}
then use that in the following way:
guess = Integer.parseInt(line);

Related

How to use Scanner hasNextInt() inside a while loop?

I cannot get out of while loop.
I do not why sc.hasNextInt() does not return false after last read number.
Should I use another method or is there a mistake in my code?
public static void main(String[] args) {
// Creating an array by user keyboard input
Scanner sc = new Scanner(System.in);
System.out.println("Length of array: ");
int[] numbers = new int[sc.nextInt()];
System.out.printf("Type in integer elements of array ", numbers.length);
int index = 0;
**while ( sc.hasNextInt()) {**
numbers[index++] = sc.nextInt();
}
// created method for printing arrays
printArray(numbers);
sc.close();
}
Do the following:
Use the input length as the end of the loop.
// Creating an array by user keyboard input
Scanner sc = new Scanner(System.in);
System.out.println("Length of array: ");
int len = sc.nextInt();
int[] numbers = new int[len]; // use len here
System.out.printf("Type in integer elements of array ", numbers.length);
int index = 0;
for (index = 0; index < len; index++) { // and use len here
numbers[index] = sc.nextInt();
}
// created method for printing arrays
printArray(numbers);
sc.close();
And don't close the scanner.
When you are receiving your input from the console, the Scanner hasNextInt() method placed inside a while loop condition will continue to read (meaning the loop will continue), until one of the following happens:
You submit a non-numeric symbol (e.g. a letter).
You submit a so-called "end of file" character, which is a special symbol telling the Scanner to stop reading.
Thus, in your case you cannot have the hasNextInt() inside your while loop condition - I am showing a solution below with a counter variable that you can use.
However, the hasNextInt() method inside a while loop has its practical usage for when reading from a different source than the console - e.g. from a String or a file. Inspired from the examples here, suppose we have:
String s = "Hello World! 3 + 3.0 = 6 ";
We can then pass the string s as an input source to the Scanner (notice that we are not passing System.in to the constructor):
Scanner scanner = new Scanner(s);
Then loop until hasNext(), which checks if there is another token of any type in the input. Inside the loop, perform a check if this token is an int using hasNextInt() and print it, otherwise pass the token to the next one using next():
while (scanner.hasNext()) {
if (scanner.hasNextInt()) {
System.out.println("Found int value: " + scanner.next());
} else {
scanner.next();
}
}
Result:
Found int value: 3
Found int value: 6
In the example above, we cannot use hasNextInt() in the while loop condition itself, because the method returns false on the first non-int character that it finds (so the loop closes immediately, as our String begins with a letter).
However, we could use while (hasNextInt()) to read the list of numbers from a file.
Now, the solution to your problem would be to place the index variable inside the while loop condition:
while (index < numbers.length) {
numbers[index++] = sc.nextInt();
}
Or for clarity`s sake, make a specific counter variable:
int index = 0;
int counter = 0;
while (counter < numbers.length) {
numbers[index++] = sc.nextInt();
counter++;
}

Scanner is not detecting first user input

My scanner is not detecting my first input, but it is detecting the second.
More info below.
Here's my code:
static int rows = 5; static int columns = 4; static int elementsEntered = 0;
static boolean leave = false;
static Scanner s = new Scanner(System.in);
static String input;
int[][] iarray = new int[rows][columns];
//Populates int array
System.out.println("In the int array");
for(int r = 0; r<iarray.length; r++) //runs through each row
{
for(int c = 0; r<iarray[0].length; c++) //runs through each column
{
System.out.println("Enter the next Element: (or # to stop)");
input = s.next();
if(s.hasNext() && input.equals("#")) //sentinel condition
{
leave = true;
break;
} else if (s.hasNextInt()) //populates array with inputs
{
iarray[r][c] = s.nextInt();
elementsEntered++;
s.nextLine();
} else
{
leave = true;
break;
}
}
if(leave)
{
break;
}
}
When I run it nothing happens after the first time I type something and press enter. Likewise, nothing happens if I press enter multiple times. But the second time I enter a value and press enter, then it gets entered into the array. Also, my sentinel condition faces the same issue.
So why is my scanner not detecting the first value I enter? I assume its something with the scanner functions I'm using but I can't figure out why.
Thanks
Edit: I found a solution. I removed the s.hasNext() and s.hasNextInt conditions and I changed
input = s.next();
to
input = s.nextLine();
and got the int value by parsing it from input.
I think that previous response could help you to improve your code and solve the issue.
Enhanced for loop does not work with Scanner inside loop body
Is not a good practice break the loop. for that particular event you can use the second parameter of the for loop
for example
for(int c = 0; r<iarray[0].length && !leave; c++){...

Provide loop conditions that are not Boolean

I need to accept some positive integers for which I use a for loop as follows:
Scanner in = new Scanner(System.in);
for(int i=0; i<n; i++) {
num = in.nextInt();
//do something with num
}
This requires me to (a) know number of integers n beforehand (b) Use a counter i
I know Java does not accept non-Boolean expressions in loop conditions. But how can I do the same without n and i?
For example, something like:
while( (num = in.nextInt()) ) {
//do something with num
}
Any type of loop (for/while/do-while) will do.
What you can do is something like:
boolean loop = true;
while (loop) {
int num = in.nextInt();
... do something with n
if (whatever) loop = false;
}
for example.
Or you use while (true) together with if (whatever) break.
In other words: you need a boolean condition, but you can control that condition within your loop body as shown above.
Loop until end of input -or- non-integer input (e.g. "exit", blank line):
while(in.hasNextInt()) {
int num = in.nextInt();
}
If you're testing in IntelliJ and want to indicate EOF explicitly: Ctrl+D or ⌘+D
If you want to read a file as your input: java MyClass < numbers.txt
Here is an example on how to use the scanner class: https://www.tutorialspoint.com/java/util/scanner_nextint.htm
You should use the hasNext() method to end the loop and check for integers with the hasNextInt() method:
public class ScannerDemo {
public static void main(String[] args) {
String s = "Hello World! 3 + 3.0 = 6.0 true ";
// create a new scanner with the specified String Object
Scanner scanner = new Scanner(s);
// find the next int token and print it
// loop for the whole scanner
while (scanner.hasNext()) {
// if the next is a int, print found and the int
if (scanner.hasNextInt()) {
System.out.println("Found :" + scanner.nextInt());
}
// if no int is found, print "Not Found:" and the token
System.out.println("Not Found :" + scanner.next());
}
// close the scanner
scanner.close();
}
}
I know Java does not accept non-Boolean expressions in loop conditions.
To my knowledge no programing language allows that. The loop either continues or it does not, this is a boolean decision and that requires a boolean conditional. There is no "the loop maybe continues, we don't know".
With that said Java - of course - requires a boolean condition to continue or not. The question you need to answer is: When shall the loop terminate?
There are three options:
The loop continues forever
while (true)
The loop stops at a special input value
while ((num = in.readInt()) != 0)
The loop is broken from outside
while (running) {
// ...
}
public void stopLoop() {
running= false;
}

How to use for loop to input 10 numbers and print only the positives?

I'm trying to make a "for" loop in which it asks the user to input 10 numbers and then only print the positives.
Having trouble controlling the amount of inputs. I keep getting infinite inputs until I add a negative number.
import java.util.Scanner;
public class ej1 {
public static void main(String args[]) {
int x;
for (x = 1; x >= 0; ) {
Scanner input = new Scanner(System.in);
System.out.print("Type a number: ");
x = input.nextInt();
}
}
}
From a syntax point of view, you've got several problems with this code.
The statement for (x = 1; x >= 0; ) will always loop, since x will always be larger than 0, specifically because you're not introducing any kind of condition in which you decrement x.
You're redeclaring the scanner over and over again. You should only declare it once, outside of the loop. You can reuse it as many times as you need.
You're going to want to use nextLine() after nextInt() to avoid some weird issues with the scanner.
Alternatively, you could use nextLine() and parse the line with Integer.parseInt.
That said, there are several ways to control this. Using a for loop is one approach, but things get finicky if you want to be sure that you only ever print out ten positive numbers, regardless of how many negative numbers are entered. With that, I propose using a while loop instead:
int i = 0;
Scanner scanner = new Scanner(System.in);
while(i < 10) {
System.out.print("Enter a value: ");
int value = scanner.nextInt();
scanner.nextLine();
if (value > 0) {
System.out.println("\nPositive value: " + value);
i++;
}
}
If you need to only enter in ten values, then move the increment statement outside of the if statement.
i++;
if (value > 0) {
System.out.println("\nPositive value: " + value);
}
As a hint: if you wanted to store the positive values for later reference, then you would have to use some sort of data structure to hold them in - like an array.
int[] positiveValues = new int[10];
You'd only ever add values to this particular array if the value read in was positive, and you could print them at the end all at once:
// at the top, import java.util.Arrays
System.out.println(Arrays.toString(positiveValues));
...or with a loop:
for(int i = 0; i < positiveValues.length; i++) {
System.out.println(positiveValues[i]);
}
Scanner scan = new Scanner(System.in);
int input=-1;
for(int i=0;i<10;i++)
{
input = sc.nextInt();
if(input>0)
System.out.println(input);
}

Java: can you change the value of the same string every time it loops?

I'm doing a very basic calculator program in java that asks for the users input, and based on what he inputs(if "add" or else) either adds up the two values or subtracts them.
The problem is, i want it to loop, so after every equation is finished and the result is displayed, it asks the user again if he wants to add or subtract. Is there any way, without using arrays, to change the value of the String each time the program loops?
import java.util.Scanner;
public class BasicCalculator {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
for(int i = 0; i<999; i++) {
System.out.println("Do you want to add or subtract?");
String answer1 = input.nextLine();
if (answer1.equalsIgnoreCase("add")) {
System.out.println("Enter first value");
int addv1 = input.nextInt();
System.out.println("Enter second value");
int addv2 = input.nextInt();
int ans = addv1 + addv2;
System.out.println("The answer is: " + ans);
} else {
System.out.println("Enter first value");
int subv1 = input.nextInt();
System.out.println("Enter second value");
int subv2 = input.nextInt();
int ans2 = subv1 - subv2;
System.out.println("The answer is: " +ans2);
}
}
}
}
Each time you assign a value to the String variable, answer1, it refers to a new String object, and the reference to the old String object is lost. So, no, you are not changing the value of the same String (and you can't, since String is immutable), you are changing the String that the variable is referring to.
I'm not clear on what your problem is, but I suspect it's this: Each line you input ends with a "new line" character. The nextInt functions will retrieve the next integer from the input, but they do not "consume" the newline character. Therefore, when you go back to the top of the loop and say
String answer1 = input.nextLine();
it will give you everything on the current line, up to the newline character. What this actually means is that it will give you an empty string, since that's all that's left on the current line after the previous integer is consumed.
If your program isn't working, try putting an additional nextLine() at the end of the loop:
for(int i = 0; i<999; i++) {
System.out.println("Do you want to add or subtract?");
String answer1 = input.nextLine();
if (answer1.equalsIgnoreCase("add")) {
// etc.
}
input.nextLine(); // ADD THIS
}
This will "consume" the leftover newline character, so that when you go back to the top, it will actually let the user enter another line.
P.S. See David's answer, which gives you a much better way of deciding when to leave the loop. (But you still need to add the nextLine.)
The problem is after you call int subv2 = input.nextInt();, the buffer has a newline character left, so that the following loop iteration, input.nextLine()is just an empty line. To fix this add a call to nextLine() after each iteration.
While the other posters are correct that "strings are immutable", you can achieve the effect you want with an "infinite" do..while loop that checks for a condition to break out of it, like so:
do {
System.out.println("Do you want to add, subtract, or quit?"); // changed this
String answer1 = input.nextLine();
if (answer1.equalsIgnoreCase("quit")) {
// check for "quit" value, and call break if that's what the user wants
break;
}
if (answer1.equalsIgnoreCase("add")) {
System.out.println("Enter first value");
int addv1 = input.nextInt();
System.out.println("Enter second value");
int addv2 = input.nextInt();
int ans = addv1 + addv2;
System.out.println("The answer is: " + ans);
} else { // this will catch anything that's not "add" or "quit". You might want to guard against that
System.out.println("Enter first value");
int subv1 = input.nextInt();
System.out.println("Enter second value");
int subv2 = input.nextInt();
int ans2 = subv1 - subv2;
System.out.println("The answer is: " +ans2);
}
} while (true); // will repeat forever until `break` is called

Categories