Is there a way around not advancing a line with Scanner (Java) - java

Okay so I'm having a slight problem with scanner advancing an extra line. I have a file that has many lines containing integers each separated by one space. Somewhere in the file there is a line with no integers and just the word "done".
When done is found we exit the loop and print out the largest prime integer that is less than each given integer in each line(if integer is already prime do nothing to it). We do this all the way up until the line with "done".
My problem: lets say the file contains 6 lines and on the 6th line is the word done. My output would skip lines 1, 3 and 5. It would only return the correct values for line 2 and 4.
Here's a snippet of code where I read the values in:
Scanner in = new Scanner(
new InputStreamReader(socket.getInputStream()));
PrintStream out = new PrintStream(socket.getOutputStream());
while(in.nextLine() != "done"){
String[] arr = in.nextLine().split(" ");
Now I sense the problem is that the nextLine call in my loop advances the line and then the nextline.split call also advances the line. Thus, all odd number lines will be lost. Would there be another way to check for "done" without advancing a line or is there a possible command I could call to somehow reset the scanner back to the start of the loop?

The problem is you have 2 calls to nextLine() try something like this
String line = in.nextLine();
while (!"done".equals(line)) {
String[] arr = line.split(" ");
// Process the line
if (!in.hasNextLine()) {
// Error reached end of file without finding done
}
line = in.nextLine();
}
Also note I fixed the check for "done" you should be using equals().

I think you are looking for this
while(in.hasNextLine()){
String str = in.nextLine();
if(str.trim().equals("done"){
break;
}else{
String[] arr = str.split("\\s+");
//then do whatever you want to do
}
}

Related

Input multiple lines using hasNextLine() is not working in the way that I expected it to

I'm trying to input multiple lines in java by using hasNextline() in the while loop.
Scanner sc = new Scanner(System.in);
ArrayList<String> lines = new ArrayList<>();
while (sc.hasNextLine()) {
lines.add(sc.nextLine());
System.out.println(lines)
}
The code is inside the main method. But the print method in thewhile loop doesn't print the last line of my input. Also, while loop doesn't seem to break.
What should I do to print whole lines of input and finally break the while loop and end the program?
Since an answer that explains why hasNextLine() might be giving "unexpected" result has been linked / given in a comment, instead of repeating the answer, I'm giving you two examples that might give you "expected" result. Whether any of them suits your needs really depends on what kind of input you need the program to deal with.
Assuming you want the loop to be broken by an empty line:
while (true) {
String curLine = sc.nextLine();
if (curLine.isEmpty())
break;
lines.add(curLine);
System.out.println(curLine);
}
Assuming you want the loop to be broken by two consecutive empty lines:
while (true) {
String curLine = sc.nextLine();
int curSize = lines.size();
String LastLine = curSize > 0 ? lines.get(curSize-1) : "";
if (curLine.isEmpty() && LastLine.isEmpty())
break;
lines.add(curLine);
System.out.println(curLine);
}
// lines.removeIf(e -> e.isEmpty());

reading multiple lines of input always runs an infinite loop unless I print each line

I'm trying to process multiple lines of input from the console using a Scanner in Java, and it runs in an infinite loop unless I print out each line. For some reason the next line is not 'consumed' unless I print it. I don't want to print it, I only want to add each line to an array to process later, so I don't know how to 'consume' each line w/o printing it. Both of these loops are infinite:
while(sc.hasNext()) {
String line = sc.nextLine();
commands.add(line);
//System.out.println(line);
sc.nextLine();
}
while(sc.hasNext()) {
String line = sc.nextLine();
commands.add(line);
//System.out.println(line);
//sc.nextLine();
}
EDIT:
My scanner initialization is below, and I also edited the condition to hasNextLine(), still running an infinite loop. That print statement that prints "done" never excecutes.
Scanner sc = new Scanner(System.in);
ArrayList<String> commands = new ArrayList<String>();
while(sc.hasNextLine()) {
String line = sc.nextLine();
commands.add(line);
//System.out.println(line);
//sc.nextLine();
}
System.out.println("done");
You should be calling hasNextLine(), not hasNext().
Printing has nothing to do with it. Printing doesn't terminate loops.
EDIT If you are never seeing your final "done", this isn't an infinite loop at all, it is a block: you're never sending an end of stream to System.in. Type Ctrl/d or Ctrl/z depending on Windows vs. Unix/Linux/... and again, printing has nothing to do with it.

How to pull int value from text file of strings and ints?

I'm trying to write a program that is practically a stack. Given a text file with certain keywords, I want my program to evaluate the text line by line and perform the requested action to the stack.
For example, if the input file is:
push 10
push 20
push 30
The resulting stack should look like:
30
20
10
However, I don't know how to push these values into the stack without hardcoding an int value after the word push. I made a String variable and assigned it to scanner.nextLine()
From there, I compare the line with strLine: if strLine is equal to push followed by some Number, then that number would be pushed on the stack.
However, it seems that the method nextInt() isn't taking this number from the input stream.
Scanner input = new Scanner(file)
int number;
String strLine;
while (input.hasNextLine()){
strLine = input.nextLine();
number = input.nextInt();
if(strLine.equals("push " + number)){
stack.push(number);
}
How can I fix this?
Thank you.
Get the input and split it with space " "!
That will give ["push","1"]
convert the first index to int and then push the value to stack!
while (input.hasNextLine()){
String[] strLine = input.nextLine().split(" ");
if(strLine[0].equals("push")){
stack.push(Integer.parseInt(strLine[1]));
}
else if(strLine[0].equals("pop")){
stack.pop();
}
else{
system.out.println("Please enter a valid input!");
}
}
Hope it helps!
input.nextLine reads the whole line, including the number. What you can do instead is to use input.next() to get the "push" and input.nextInt() to get the number. This example is using Scanner with System.in (so it needs "quit" to exit the while loop), but it should also work with a file (in which case you don't need to type "quit" to exit the program, as it will do so automatically when the input file has no more input). The advantage of using parseInt (as some of the other answers have suggested) is that you can catch any errors in integer input using a try/catch block.
import java.util.Scanner;
import java.util.Stack;
import java.util.InputMismatchException;
public class StackScanner {
public static void main(String args[]) {
Stack<Integer> stack = new Stack<Integer>();
Scanner input = new Scanner(System.in);
int number;
String strLine;
while (input.hasNext()){
strLine = input.next();
if(strLine.equals("push")){
try {
number = input.nextInt();
stack.push(number);
} catch ( InputMismatchException e) {
System.out.println("Invalid input. Try again.");
input.nextLine();
continue;
}
} else {
break;
}
}
System.out.println(stack);
}
}
Sample output:
push 5
push 6
push 3
quit
[5, 6, 3]
change this:
number = input.nextInt();
to this:
number = Integer.parseInt(input.nextLine());
nextLine method parses the whole line including any numbers in the line. So, you need to take care of splitting the line and parsing the number in your code.
Something like below will work where I split the line with spaces. Although, there are many such ways possible.
Scanner input = new Scanner(file);
String strLine;
Stack<Integer> stack = new Stack<>();
int number;
while (input.hasNextLine()){
strLine = input.nextLine();
if(strLine.startsWith("push")){
String[] sArr = strLine.split("\\s+");
System.out.println(strLine);
if(sArr.length==2){
number=Integer.parseInt(sArr[1]);
stack.push(number);
System.out.println(number);
}
}
}
If I understand your problem, I would simply tokenize the line by splitting on whitespace.
It looks like your input is relatively structured: you have a keyword of some kind then whitespace then a number. If your data is indeed of this structure, split the line into two tokens. Read the value from the second one. For example:
String tokens[] = strLine.split(" ");
// tokens[0] is the keyword, tokens[1] is the value
if(tokens[0].equals("push")){
// TODO: check here that tokens[1] is an int
stack.push(Integer.parseInt(tokens[1]));
} else if (tokens[0].equals("pop")) { // maybe you also have pop
int p = stack.pop();
} else if ... // maybe you have other operations

Reading input from a file, Scanner.nextLine() produces blank result

So, my end goal is to use an input file to instantiate an ArrayList of Letter objects. The file contains multiple cases of the following format:
from-to
line 1
...
line n
(*** is used as an indicator of a new letter. There are no blank lines between input lines, in other words, each line is followed immediately by a return and then the next line.)
Yet before I even attempt to instantiate multiple Letter objects, I am just trying to get the first one to work.
Scanner in = new Scanner(_file).useDelimiter("\\s+?|-");
ArrayList<Letter> letters = new ArrayList();
String from = in.next();
String to = in.next();
Letter temp = new Letter(from,to);
String s = in.next();
temp.addLine(s);
Where a Letter object takes two strings for the recipient and writer and can then have lines added to it. So my output should be:
Dear Recipient:
Line 1
...
Line n
Sincerely,
Writer
But when I use this my output is:
Dear Recipient:
Sincerely,
Writer
The documentation Scanner.nextLine() says this:
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.
So what the method actually does is give you whats left on that line only
So, you need to do this:
Scanner in = new Scanner(_file).useDelimiter("\\s+?|-");
ArrayList<Letter> letters = new ArrayList();
String from = in.next();
String to = in.next();
Letter temp = new Letter(from,to);
in.nextLine(); // <-- this is extra
// now we're ready to read the rest of the stuff
String s = in.nextLine();
temp.addLine(s);

Scanner problems in Java

I have a method that returns a scanner to a text file that has lines of input (I can't get this to display properly, but like - Hi (new line) This (\n) Is (\n) Me (\n)). Then in main, I used the scanner to count the number of lines of input there are, and then resetted the scanner. I later used the scanner to put the lines of input into an array (I don't want an ArrayList), but Java says "java.util.NoSuchElementException: No line found"...
while(scanner.hasNextLine()){
numOfStrings++;
scanner.nextLine();
}
scanner.reset();
String[] stringsOfInput = new String[numOfStrings];
for(int i = 0; i < numOfStrings; i++){
String s = scanner.nextLine(); //returns "No line found" error message
stringsOfInput[i] = s;
}
Does anyone know how to fix this so it does what it should?
The most versatile way to do this would be to add the lines into an ArrayList<String> then make that into an Array(String[] stringsOfInput = myArrayList.toArray(new String[myArrayList.size()]);)
You may want to try putting the content of the for loop within the while. That way you can get the number of strings and each string in one loop through the file.
EDIT:
Sample with ArrayList
ArrayList<String> stringsOfInput = new ArrayList<String>();
while(scanner.hasNextLine())
{
stringsOfInput.add(scanner.nextLine());
numOfStrings++;
}

Categories

Resources