I don't really get the behaviour of the Scanner. I want to input a single int first and in the while-loop, as you can see, next line inputs. But after the first input I get an ArrayOutOfBoundsException as you can see below. It just ignores that I want to input next lines. The only solution is when I input the int and the new line separated with a space in one line, but that isn't what I want, because at this point, the user doesn't know, what to input after the first int.
Scanner scanner = new Scanner(System.in);
int i = scanner.nextInt() - 1;
logic.setGameField(games.get(i).getGameField());
// scanner.reset(); //what does that do?
view.displayField(logic.getCompleteGameField(), logic.getGameSize(), logic.getCompleteGameSize());
double time = System.currentTimeMillis();
while (!logic.gameIsFinished()) {
System.out.println("Spalte Reihe Zeichen: X/*");
String s = scanner.nextLine();
char[] tmp = s.toCharArray();
//just for testing
System.out.println(s.length()); //outputs: 0
System.out.println(tmp.length); //outputs: 0
for (int j = 0; j < tmp.length; j++) {
System.out.print(tmp[j] + " " + j);
}
System.out.println();
logic.setSingleField(tmp[1] - CHAR_TO_INT_OFFSET_ROW, tmp[0] - CHAR_TO_INT_OFFSET_COLUMN, tmp[2]); //throws as expected ArrayIndexOutOfBoundsException
This is because Scanner.nextInt() doesn't bring you to the next line. At this point, you are still in current line of input. What you can do is call an additional Scanner.nextLine() after Scanner.nextInt():
int i = scanner.nextInt() - 1;
scanner.nextLine();
logic.setGameField(games.get(i).getGameField());
Related
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++;
}
I want to get two string inputs into a string array
String[] b = new String[n];
by using scanner but the scanner automatically takes blank value in
b[0].i.e. it skips the first loop.
Scanner scn = new Scanner(System.in);
int no = 0;
int n = scn.nextInt();
String[] b = new String[n];
for (int j = 0; j < n; j++) {
System.out.println("Enter the string");
b[j] = scn.nextLine();
}
the output occurs like
2
Enter
Enter
abc
can anyone suggest me why this problem occurs??
This is because nextInt() does not read the \n in your input. This is then read by your nextLine()
More explanation,
When you enter a number when prompted by the nextInt() call. You type a number and press Enter This makes your input look like this
10\n
nextInt() reads only the 10 and leaves out \n.
Then, your nextLine() reads only the \n.
This explains your output.
You can get the expected output by having an extra nextLine() after the nextInt().
See this for more information on it.
In this code I can get upto only 2 values instead of 3 input values. Why does it so? Please explain me.
Scanner input = new Scanner(System.in);
System.out.println("Enter how many string to get");
int size;
size = input.nextInt();
String arr[] = new String[size];
System.out.println("Enter strings one by one");
for(int i = 0; i < size; i++) {
arr[i] = input.nextLine();
System.out.println(i);
}
nextInt will get the integer from the input buffer and will leave the new line character in the buffer. So when you call nextLine after that, the new line character in the buffer will be returned. To fix this, add a nextLine after calling nextInt
Scanner input = new Scanner(System.in);
System.out.println("Enter how many string to get");
int size;
size = input.nextInt();
input.nextLine();//get the new line character and ignore it
String arr[] = new String[size];
System.out.println("Enter strings one by one");
for(int i = 0; i < size; i++) {
arr[i] = input.nextLine();
System.out.println(i);
}
See the answer from this link , it explains in detail what you are experiencing: Using scanner.nextLine()
In short the first nextLine reads the rest of the line from your nextInt call.
Use input.nextInt() instead of input.nextLine().
nextLine() reads input including space between the words (that is, it reads till the end of line \n). Once the input is read, nextLine() positions the cursor in the next line.
next() reads the input only till the space. It doesnt read the space between words.
same as thisquestion I want to get input from user while he/she give me strings. but the difference is that now before I get strings , I must get 26 numbers. so this code works wrong in getting myStrings. what should I do?
Wrong code:
for (int i = 97; i < 123; i++) {
alphabet[i] = scan.nextFloat();
}
String infix;
int i = 0;
String[] myStrings = new String[100];
while (scan.hasNextLine()) {
infix = scan.nextLine();
if (infix.length() > 0) {
myStrings[i] = infix;
i++;
} else {
break;
}
}
edit: wrong means , when I debug it, before I give strings as an input (after giving numbers) , this line :(" while (scan.hasNextLine()) ") passes , and infix in this line( infix = scan.nextLine(); is "") so the while , doesn't work correct. and break after that.
The issue is that after reading a float from the scanner, a newline "\n" is left in the scanner, this means that when the first scan.nextLine() runs, it gets that leftover newline, which results in your code hitting the else block, and breaking out of the loop.
You can either get the next line before your loop:
String infix;
int i = 0;
String[] myStrings = new String[100];
infix = scan.nextLine(); //Get it here to throw away the new line
while (scan.hasNextLine()) {
infix = scan.nextLine(); //Should contain whatever the user entered
//code
}
Or, when you get the float from the loop, you can use Float.parseFloat() combined with scan.nextLine(), like so:
for (int i = 97; i < 123; i++) {
alphabet[i] = Float.parseFloat(scan.nextLine());
}
Which will stop there from being a new line left in the scanner after you receive the last float
That's a common issue in Java. After getting the input from user using Scanner like nextInt();, nextDouble(); etc, you need to consume a line with a empty scan.nextLine();, because those methods doesn't consume the new line expression "\n". , before you can get some strings.
I have a small task that allows the user to enter the regions and their neighbors of any country.
I did everything and I just have a small problem which is when I run my code and the program asks the user to enter the number of regions, if the user enters 13 or and number greater than 10, the system will consider that number is like two inputs and it will not allow the user to enter anything for the second question and it will prompt him with the third question immediately. Why?
I think the problem with the Scanner class in the following command:
Scanner kb = new Scanner(System.in);
System.out.print("Please enter the number of regions: ");
int REGION_COUNT = kb.nextInt();
region = new CountryRegion[REGION_COUNT];
String[] neighbours;
for (int r = 0; r < region.length; r++) {
System.out.print("Please enter the name of region #" + (r + 1) + ": ");
String regionName = kb.nextLine();
System.out.print("How many neighbors for region #" + (r + 1) + ": ");
if (kb.hasNextInt()) {
int size = kb.nextInt();
neighbours = new String[size];
for (int n = 0; n < size; n++) {
System.out.print("Please enter the neighbour #" + (n + 1) + ": ");
neighbours [n] = kb.nextLine();
}
region [r] = new CountryRegion(regionName, neighbours);
}
else
System.exit(0);
}
for (int i = 0; i < REGION_COUNT; i++) {
System.out.print(region[i].getRegionName() +": ");
for (int k = 0; k < region[i].getRegionAjesint().length; k++) {
System.out.print(region[i].getRegionAjesint()[k] +", ");
}
System.out.println();
}
mapColor = new MapColor(region);
Any help, please?
Ok, Very simple your problem is that you are using the nextInt() method of the Scanner class and then using the nextLine() method both of these use the same buffer and here is what's happening.
When you enter the number your asking (let say 10) in the key board your actually entering
10 and the enter key (new line character (\n))
The nextInt() method from the Scanner class will read the 10 and just the 10 that meaning that the new line character (\n) is still in the keyboard buffer and next in your code you have a nextLine() which will read everything up to a new line (\n), which you already have in the buffer!!!
So the way this is all working is that the nextLine() method considers the new line character (\n) left in the buffer as it's input and there for continues to the next iteration of the loop.
The solution to your problem is to clear the buffer of the new line character (\n) you can achieve this by calling a nextLine() method before the actual one in your code like so:
...
int REGION_COUNT = kb.nextInt();
region = new CountryRegion[REGION_COUNT];
String[] neighbours;
kb.nextLine(); //CLEAR THE KEYBOARD BUFFER
for (int r = 0; r < region.length; r++) {
System.out.print("Please enter the name of region #" + (r + 1) + ": ");
String regionName = kb.nextLine();
...
This way the nextLine() called extracts the new line character from the buffer, clearing it, and since it doesn't store it it gets discarded leaving you with a new line character free buffer ready to receive full input from the user in your nextLine() method.
Hope this helps.
Sounds like each key press is an input.
You are using nextLine() to get the String but I think you should be using next().