Why java Scanner is not reading all the lines? - java

Here is my code which just reads the lines from input stream and displays them but to my surprise its not reading all the lines. Its reading only upto second last line.
Here is my code :-
import java.util.*;
public class Solution {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
short n = scan.nextShort();
short m = scan.nextShort();
byte[][] topics = new byte[n][m];
for(short i = 0; i < n; i++){
char[] arr = scan.nextLine().toCharArray();
display(arr);
}
}
private static void display(char[] arr){
for(int i = 0; i < arr.length; i++){
System.out.print(arr[i]);
}
System.out.println();
}
}
The input is given in this format
4 5
10101
11100
11010
00101
My output is this :-
10101
11100
11010
Its not having the third line. Why?

Add a scan.nextLine() before your for loop, to read the end of the first line (that contains "4 5"). Without it, the first call to scan.nextLine() inside the loop returns an empty String.

The problem is that the first call to nextLine() is reading the empty "line" between the end of "5" (read for m) and the line break.
Personally, I would either stop using Scanner entirely (in favour of BufferedReader) - there's a huge number of questions a bit like this, with it not behaving exactly as you'd like - or only just nextLine(). Either way, basically process a line at a time:
Read the first line
Split it on space and parse the two substrings as n and m
Read the next n lines
Basically, Scanner is "token-oriented" whereas your input format is more "line-oriented".
If you do want to use Scanner.nextShort() you could always read the first line (either with a BufferedReader or a Scanner) and create a new scanner just from that string:
String firstLine = ...;
Scanner firstLineScanner = new Scanner(firstLine);
short n = firstLineScanner.nextShort();
short m = firstLineScanner.nextShort();
...

The problem is scan.nextLine() just remove this and put
scan.next() if you read about nextLine method this might help
public String nextLine()
Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line.
Since this method continues to search through the input looking for a line separator, it may buffer all of the input searching for the line to skip if no line separators are present.
public class Solution
{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
short n = scan.nextShort();
short m = scan.nextShort();
short[][] topics = new short[n][m];
for(short i = 0; i < n; i++){
char[] arr = scan.next().toCharArray();
display(arr);
}
}
private static void display(char[] arr){
for(int i = 0; i < arr.length; i++){
System.out.print(arr[i]);
}
System.out.println();
}
}

Related

How do you take an undefined amount of inputs from scanner?

I am making a search engine to find what document matches the words given by the user. The following is my code:
Scanner userInput = new Scanner(System.in);
System.out.println("\n\n\nEnter the words you would like to search your documents for (up to 10):");
String[] stringArray = new String[10];
int i = 0;
// Takes input until user leaves a blank line or max is reached.
while (userInput.hasNext() && i < 9){
stringArray[i] = userInput.next();
i++;
}
for (int j = 0; j < i; j++){
System.out.println(stringArray[j]);
}
This is my method that actually takes the user input and I am going to add to it in a little bit to do the search but I tried to test this much (that's why it prints out the input) to see if it works but It keeps accepting input. What can I change so that it takes as many words as the user puts them until they leave a line blank? I got it to stop at 10 but I thought hasNext() would stop it when they leave a line blank but it just keeps scanning.
hasNext() & next() stop at words, not lines. With your code, the user could put all 10 words on the same line and they'd be done. Also, these methods will skip all whitespace, including newline characters, until they find the next word. You can't look for a blank line using hasNext() and next() can never return an empty string. You want hasNextLine() and nextLine() instead.
Scanner userInput = new Scanner(System.in);
System.out.println("\n\n\nEnter the words you would like to search your documents for (up to 10):");
String[] stringArray = new String[10];
int i = 0;
while (i < stringArray.length
&& userInput.hasNextLine()
&& !(stringArray[i] = userInput.nextLine().trim()).isEmpty()) {
i++;
}
for (int j = 0; j < i; j++) { // just for testing purposes
System.out.println(stringArray[j]);
}
But why limit yourself to just 10 lines? You can use ArrayList instead for more flexibility:
Scanner userInput = new Scanner(System.in);
System.out.println("\n\n\nEnter the words you would like to search your documents for:");
List<String> stringList = new ArrayList<>();
String line;
while (userInput.hasNextLine()
&& !(line = userInput.nextLine().trim()).isEmpty()) {
stringList.add(line);
}
stringList.forEach(System.out::println); // just for testing purposes
Change your while loop to this:
while (!(String temp = userInput.nextLine()).trim().contentEquals("")) {
stringArray[i] = userInput.next();
i++;
}
String line;
int i = 0;
while(!(line = userInput.nextLine()).isEmpty()) {
for (String word :line.split("\\s+")){
stringArray[i]=word;
i++;
}
}
This code assigns every line from Scanner into variable line until is not user input empty. In every iteration it splits line to words and assigns to stringArray.

Java Input method not terminating

I'm trying to work out this problem:
Input
The input stream contains a set of integer numbers Ai (0 ≤ Ai ≤ 1018). The numbers are separated by any number of spaces and line breaks. A size of the input stream does not exceed 256 KB.
Output
For each number Ai from the last one till the first one you should output its square root. Each square root should be printed in a separate line with at least four digits after decimal point.
Sample:
input:
1427 0
876652098643267843
5276538
output:
2297.0716
936297014.1164
0.0000
37.7757
And here's my code:
public class ReverseRoot
{//start class
public static void main(String[] args)
{//start main
Scanner in = new Scanner(System.in);
ArrayList<Long> array = new ArrayList<Long>();
array.add(in.nextLong());
while(in.hasNextLong())
{
array.add(in.nextLong());
}
in.close();
for (int i = array.size(); i > 0; i--)
System.out.printf("%.4f%n", Math.sqrt((double)array.get(i)));
}//end main
}//end class
Anybody know what the deal is?
Your for loop doesn't work because you try to access non existing elements in your list.
Change the loop to this:
for (int i = array.size() - 1; i >= 0; i--)
System.out.printf("%.4f%n", Math.sqrt((double)array.get(i)));
}
Why do you have array.add(in.nextLong()); outside the loop? You can delete this.
To exit your input just type any non-long character into your console.
As I observer, we should have 2 loops. The first loop is for 'multiple lines' and the second loop is for 'multiple long value' of a single line.
Here is an example
public static void main(String[] args) throws Exception {
Scanner console = new Scanner(System.in);
Scanner lineTokenizer;
// this is to handle all 'lines'
while (console.hasNextLine()) {
String lineContent = console.nextLine();
if (lineContent == null || lineContent.isEmpty()) {
// this is to exit the program if there is no input anymore
break;
}
lineTokenizer = new Scanner(lineContent);
// this is to handle a 'line'
while (lineTokenizer.hasNext()) {
if (lineTokenizer.hasNext()) {
long number = lineTokenizer.nextLong(); // consume the valid token
System.out.printf("%.4f%n", Math.sqrt((double) number));
}
}
lineTokenizer.close(); // discard this line
}
console.close(); // discard lines.
}

String not parsing correctly with a space

I am a very new to Java, so my knowledge is very limited. I have been trying to find the problem in this block of code.
import java.util.Scanner;
public class avgFinder {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Input numbers to average. Separate by a space.");
String nums = scan.next();
String[] parseNums = nums.split("[ ]");
double sum = 0;
int cnt = 0;
for (int a=0; a<=parseNums.length-1; a++) {
sum += Double.parseDouble(parseNums[a]);
cnt++;
}
double mean = sum/cnt;
System.out.println("Mean: " + mean);
}
}
But when I input a a set of numbers, only the first number gets printed instead of the actual mean. Example:
Input numbers to average. Separate by a space.
1 2 3
Mean: 1.0
Another thing is if I replace nums.split("[ ]") with nums.split("[,]") and put commas instead of spaces between the numbers in the output, it actually outputs the mean. I like spaces better though, it looks cleaner. Why is this happening?
Try this
use nextLine() instead of next()
nextLine returns complete line of text while next returns only one word
Also use nums.split(" ");
import java.util.Scanner;
public class avgFinder {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Input numbers to average. Separate by a space.");
String nums = scan.nextLine();
String[] parseNums = nums.split(" ");
double sum = 0;
int cnt = 0;
for (int a=0; a<=parseNums.length-1; a++) {
sum += Double.parseDouble(parseNums[a]);
cnt++;
}
double mean = sum/cnt;
System.out.println("Mean: " + mean);
}
}
Calling Scanner.next() will return the next element in a line before a space, so you only getting the first number in your input. Use Scanner.nextLine() which will return all the values on that line.
Scanner.next() returns the next word. By default, words are separated by whitespace. So when you call Scanner.next(), your scanner reads the digits of the first number, hits a space, and says "ok, that's the end of the word. Time to return the result" and you end up with just the first number.
That's why it works when you replace the spaces with commas: Without any spaces, the scanner doesn't find whitespace until it reaches the line break, so it returns the whole line.
Scanner.nextLine() returns the entire line instead of just one word (it reads until it hits a line break), so I'd suggest using that instead.

Why do I get 2 values as input not the 3 values

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.

Java while(input.hasnextline) loop not exiting?

SO I'm supposed to determine the number of lines in a text file (a 100 lines containg numbers) and then create an array with the the number of lines, but the first while loop used to find out the number of lines in the text file never exits. The second loop which is the exacts same one works just fine. Please help me out!
static void main(String[] args) throws Exception{
java.io.File file = new java.io.File("seriesOfNumbers.txt"); //file instance
Scanner input = new Scanner(file); //Scanner
int M =0 ;
while (input.hasNextLine() && !input.equals(null))// ** Loop never exits, tried almost everything
{
k++;
}
double[] numberArray = new double[k];
int V = 0;
while (input.hasNextLine())// When I exit the first loop this one exits just fine
{
numberArray[j] = (double) input.nextInt();
j++;
}
You are never consuming your input in the first loop, do that with input.nextLine().
You are now looping until input.hasNextLine() becomes false, but that never happens, because you do not consume the input.
Use input.next() to move to next line. In While condition you are checking the has next line and not null. Thats y it is in infinite loop.
In this below code,
this is initialising
Scanner input = new Scanner(file); //Scanner
This is reading
int M =0 ;
while (input.hasNextLine() && !input.equals(null))
{
input.nextLine(); // Use this to advance the lines from scanner
k++;
}
It seems to me that you could use FileUtils class from apache.commons.io project to do the trick.
static void main(String[] args) throws Exception{
List<String> lines = FileUtils.readLines(new File("..."));
Now, if you really need the numberArray for some other computation, you can
double[] d = new double[lines.size()];
Or you can use the Collection to iterate
for (String line : lines) {
double n = Double.parseDouble(line);
To use FileUtils, take a look at http://commons.apache.org/proper/commons-io/
But, iof all that you want is to know what is wrong with your code, you should call the method Scanner.nextLine() inside your first while loop.
In order to stop the infinite looping of the while loop even after consuming the required inputs, we can use a break statement.
Here is an example,
while (scanner.hasNextLine()) {
String[] arr = scanner.nextLine().split(" ");
long[] ar = new long[n];
for (int i = 0; i < n; i++) {
ar[i] = Long.parseLong(arr[i]);
}
long result = sum(ar);
System.out.println(result);
break;
}

Categories