Problem reading a file with Scanner and a cycle - java

I have two different kinds of input in a file.
First line has the number of Tasks that must be created, then the next following lines have the data each task must have, for example, lets say the file has
4
Task1 4, 5
Task2 2, 7
Task3 8, 9
Task4 7, 2
//followed by other data
I want to create an array for the tasks, and then read the info each task must contain.
So I tried:
Scanner inFile = new Scanner(new File("Readthis.txt"));
int numberOfTasks =inFile.nextInt();
Tasks myTasks = Tasks[numberOfTasks];
for (int i=0;i<numberOfTasks;i++)
{
String line = inFile.nextLine();
String[] temp = line.split(" ");
String TaskName = temp[0];
int TaskDuration = Integer.valueof(temp[1]);
//and the other process for the third number
}
My problem is, it sets the number of tasks as 4, no problem, but, when starting the "for" cycle it reads line as "" and doesn't read "Task1 4 5" and so on,
so right now it throws and exception because temp[0] is empty, but it should be the task's name.
Shouldn't Scanner keep reading where it left off? after it read the first "4"? I'm confused.
How do I get it to work as I need?

You should not use nextInt() but nextLine() to read a file line by line.
Try to replace the nextInt() line with the following:
int numberOfTasks =Integer.parseInt(inFile.nextLine());
The code will read the whole line (containing the 4 number in your example), and will try to parse it into an Integer.
The nextInt() will read the next token, and not the whole line, so after nextInt() read the 4 number, the new line bytes (\n) is left for the nextLine() to read.
Check Java 8 Scanner API.
public int nextInt()
Scans the next token of the input as an int.
...

Related

scanner.nextInt() is moving to the next line, how is this possible?

Input
Integer N
N lines follow, each line has two space seperated integers p and q.
So, I know that nextLine() reads the whole line and moves the cursor to the next line and nextFoo() reads only up till it encounters a space and keeps the cursor there (doesn't move it to a new line).
So initially I tried this:-
int N = Integer.parseInt(in.nextLine()); //reading the whole line and parsing it to Integer. The cursor pointer is moved to the next line
while(--N>=0){
p = in.nextInt(); q = in.nextInt(); //reading the two space seperated integers
in.nextLine();//to move the cursor to the next line
}
But this wasn't working properly, couldn't read the last p and q I was inputting.
Changed it to:
int N = in.nextInt();
while(--N>=0){
p = in.nextInt(); q = in.nextInt();
}
And it is working fine. How is nextInt() going to the next line? All .nextFoo() and .next() except .nextLine() read only up till there is a space and keep the cursor pointer there, right? How is this going to the newline then?
From the Scanner Javadoc:
The next() and hasNext() methods and their primitive-type companion methods (such as nextInt() and hasNextInt()) first skip any input that matches the delimiter pattern, and then attempt to return the next token.
So the cursor is before the newline, then when you call nextInt(), skips through the newline and any other whitespace, before consuming the number.
Your code containing nextLine() will work, as long as your input file ends in a newline. It's conventional to end text files with a newline character -- many editors will either force you to have one, or display a warning if it's missing.

Java Scanner, No such element exception while reading mulitple lines

I am trying to read multiple line from a file using java scanner. Each line has strings separated using comma, but there is no comma at the end of line. My text file contains value like below
98792203000000005091,89065012012341234100000000000167,084952103900000015
98792203000000005091,89065012012341234100000000000167,084952103900000015
The scanner is throwing a no element exception, it works fine if I add a comma t the end of line, but the original file will not have a comma. How do I make work
Scanner sc = new Scanner(outPutFile);
int outputDataStart = Integer.parseInt(outputDataStartLine);
skipLines(sc, outputDataStart);
sc.useDelimiter(",");
while(sc.hasNext())
{
OutputVariables outputVariables = new OutputVariables();
outputVariables.setIccid(sc.next());
outputVariables.setImsi(sc.next());
outputVariables.setKey(sc.next());
outputVariables.setPIN1(sc.next());
outputVariables.setPUK1(sc.next());
outputVariables.setPIN2(sc.next());
outputVariables.setPUK2(sc.next());
outputVariables.setPINAdm(sc.next());
outputVariables.setAccount(sc.next());
outputVariables.setKIC(sc.next());
outputVariables.setKID(sc.next());
outputVariables.setKIK(sc.next());
outputVariables.setOPCKey(sc.next());
OutputVariableList.add(outputVariables);
}
Insteard of using sc.useDelimiter(",") use sc.useDelimiter(",|\\n") it would break by both , and new line
You're asking the scanner to parse more values from a line of text than there are values. This is happening because you're calling next() without first checking hasNext(). Since you've told it to use the comma as the delimeter, it's hitting the end of the line continuing on to the next line until it finds the next comma.
Consider this CSV:
A,B,C,D
If you call next() after you parse the "D", the scanner will throw a NoSuchElementException.
It is not clear what you're attempting to do. If you're attempting to convert what is effectively a CSV into an object, then your best bet would be to use the Scanner to read each line, and then a String.split() call to split that line into parts.
If you're trying to parse multiple lines into an object, you'll of course need to figure out where your boundary is -- every fifteen comma separated values? every three lines? -- and apply that logic while collecting your segments.
As a simplified example, consider this collection of lines:
A,B,C,D
E,F,G,H
I,J,K
You would first use the Scanner to read line-by-line, and then use split each line apart and create the individual objects. Notice the last line is malformed -- you'll need to trap for that and catch it to avoid the NoSuchElementException.
Scanner sc = new Scanner(file);
while(sc.hasNext()) {
String line = sc.next();
String[] parts = line.split(",");
if(parts.length != 4) {
System.err.println("Invalid line: " + line);
continue; // skip this record, it is bad
}
// create your object here from parts
Pojo example = new Pojo(parts[0], parts[1], parts[2], parts[3]);
// etc
}
Alternatively if you're just trying to create a single massive object -- eg all lines belong to the same record -- you could tell it to consider a newline as a delimeter in addition to a comma. That way, after you hit the last comma in the first line, you would call next() and it would parse until the end of the line; and then when you called next() again, it would parse starting on the next line until it reached a comma or the end of the line, whichever came first.
I suggest you to use BufferedReader
it has a method named readLine()
first read a String then through the string.split(",") you can get the array of String

Is there a way around not advancing a line with Scanner (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
}
}

What's an elegant way to parse this text in java?

Disclaimer:
The parsing-problem described in here is very simple. This question does not simply ask for a way to achieve the parsing. - That's almost straightforward - Instead, it asks for an elegant way. That elegant way would probably be one which does not first read line-wise and then parse each line on its own, as this is obviously not necessary. However, is this elegant way possible with ready to use standard classes?
Question:
I have to parse text of the following form in java (there is more than these 3 records; records can have way more lines than these examples):
5
Dominik 3
Markus 3 2
Reiner 1 2
Samantha 4
Thomas 3
4
Babette 1 4
Diana 3 4
Magan 2
Thomas 2 4
The first number n is the number of lines in the record directly following. Each record consists of a name and then 0 to n integers.
I thought that using java.util.Scanner is a natural choice, but it leads to the nastiness that when using hasNextInt() and hasNext() to determine if a line is started, I can't distinguish if a read number is the header of the next record or it's the last number behind the last name of the previous record. Example from above:
...
Thomas 3
4
...
Here, I don't know how to tell if the 3 and the 4 is a header or belongs to the current line of Thomas.
Sure I can first read line by line, put them into another Scanner, and then read them again, but this effectively parses the whole data twice, which looks ugly to me. Is there a better way?
I would need something like a flag which tells me if a line break was encountered during the last delimiter skipping operation.
Read the file using FileReader and BufferedReader and then start checking :
outer loop -->while readLine is not null
if line matches //d+ --> read value of number and put it into count
from 0 to count do what you want to do // inner loop
Instead of reading into a separate scanner, you can read to end of line, and use String.split, like this:
while (scanner.hasNextInt()) {
int count = scanner.nextInt();
for (int i = 0 ; i != count ; i++) {
if (!scanner.hasNext()) throw new IllegalStateException("expected a name");
String name = scanner.next();
List<Integer> numbers = new ArrayList<Integer>();
for (String numStr : scanner.readLine().split(" ")) {
numbers.add(Integer.parseInt(numStr));
}
... // Do something with name and numbers
}
}
This approach avoids the need to detect the difference between the last int on a line vs. the first integer on next line by calling readLine() after reading a name, i.e. in the middle of reading a line.
File file = new File("records.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = null;
/* Read file one line at a time */
while((line = reader.readLine()) != null){
int noOfRecords = Integer.parseInt(line);
/* read the next n lines in a loop */
while(noOfRecords != 0){
line = reader.readLine();
String[] tokens = line.split(" ");
noOfRecords--;
// do what you need to do with names and numbers
}
}
Here we're reading one line at a time, so the first time we read a line it will be an int (call it as n), from there read the next n lines in some inner loop. Once it's done with this inner loop it will come outside and the next time you read a line it's definitely another int or EOF. That way you don't have to deal with integer parsing exceptions and we'll read all the lines only once :)

Reading from third line of text file

How can I start reading from the third line of text file in Java?
I want to store 12 in 'nodes' variable, 14 in'edges' variable.
12334 in different variable and so on.
My input text file consisting of integers goes like this:
12
14
12334 12214 25
32151 32151 85
21514 51454 20
.
.
.
.
.
try
{
for(i=0;i<2;i++)
array[i] = inputFile.nextInt();
nodes=array[0];
edges=array[1];
break;
for(i=2;i<5;i++)
{
array1[i] = inputFile.nextInt();
System.out.println(array1[i]);
}
}
Using Scanner:
Scanner sc = new Scanner(myFile);
int lineIndex = 0;
while(sc.hasNextLine()) {
String line = sc.nextLine();
if(++lineIndex > 3) {
// do something
}
}
Note: Having break is going to terminate the outer loop
Suggestiones how to solve this
1 . Either use BufferReader or Scanner class.
2 . Have a counter variable set to zero
3. keep reading line and check if it is equal to 3 yet
4. continue reading line, but when the counter is equal 3, save each line in either variable or Array
Difference between BufferReader and Scanner
1. BufferedReader has significantly larger buffer memory than Scanner. Use BufferedReader if you want to get long strings from a stream, and use Scanner if you want to parse specific type of token from a stream.
2. Scanner can use tokenize using custom delimiter and parse the stream into primitive types of data, while BufferedReader can only read and store String.
3. BufferedReader is synchronous while Scanner is not. Use BufferedReader if you're working with multiple threads.

Categories

Resources