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.
Related
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.
...
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
}
}
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 :)
Say I have a file called AnnualRateOfReturn.txt with a list of numbers for each line. Lets call that variable X. The numbers read from the file will be percentages.
In a loop, I want to take one variable, lets say Y, and then multiply it by 1.X value read from the first line AnnualRateOfReturn.
After it loops again, I want it to take a new value, read from the next line of the file AnnualRateOfReturn.txt, and then multiply the Y value by the new 1.X variable.
For each loop, it should read the next line and then multiply the Y variable by that value.
Example:
AnnualRateOfReturn.txt
Line1: 0.04
Line2: 0.24
On the first loop, the Y value should be multiplied by 1.04
On the second loop, the next line should be read, and the Y value should be multiplied by 1.24
I need to accomplish this with the FileReader class.
//create a Scanner to scan through the file that FileReader reads
//note: must deal with FileNotFoundException
//which will be thrown if FileReader(source) cannot find the source file
Scanner scanner = new Scanner(new FileReader("path/to/AnnualRateOfReturn.txt"));
//scanner.hasNext() ensures that the scanner has a token to read
while(scanner.hasNext()){
//create your x value, this will throw an exception if the next token isn't a Double
double x = 1 + scanner.nextDouble();
//do your math
y = y*x;
}
use Scanner to read the file
Scanner sc = new Scanner("C:\\PATH_TO_THE_FILE\\AnnualRateOfReturn.txt");
now to read a line :
String line= sc.nextLine();
to get the value :
double x=1 + Double.valueOf(line);
if you want to test if file still has lines use :
while(sc.hasNext())
and then do the math ... good luck
This question already has an answer here:
java.lang.IllegalStateException: Scanner closed
(1 answer)
Closed 4 years ago.
So I have this code and it's supposed to read data from a file called "Numbers.txt". In this file, it is simply just 2003 lines of decimal numbers. The goal of the program is to read this file and make calculations. First I had to get the mean, which I've managed to do, but the problem is I have to now go back in and get the standard deviation. It compiles fine but I get a run error as below:
Exception in thread "main" java.lang.IllegalStateException: Scanner closed
at java.util.Scanner.ensureOpen(Scanner.java:1115)
at java.util.Scanner.hasNext(Scanner.java:1379)
at StatsDemo.main(StatsDemo.java:49)
This is my code:
File rf2 = new File("Numbers.txt"); //reconnect to the FileReader object passing it the filename
Scanner inputFile2 = new Scanner(rf2);//reconnect to the BufferedReader object passing it the FileReader object.
sum = 0; //reinitialize the sum of the numbers
count = 0; //reinitialize the number of numbers added
//priming read to read the first line of the file
while (inputFile.hasNext()) //loop that continues until you are at the end of the file
{
difference = inputFile.nextDouble() - mean; //convert the line into a double value and subtract the mean
sum += Math.pow(difference,2); //add the square of the difference to the sum
count++; //increment the counter
if (inputFile.hasNextDouble())
inputFile.nextLine(); //read a new line from the file
}
inputFile.close(); //close the input file
stdDev = Math.sqrt(sum/count); //store the calculated standard deviation
I'm not sure why I'm getting this error. I got a similar (but not the same) one from the mean calculation earlier, but the resolve for that doesn't work for this. Any ideas?
After changing to inputFile2...
Exception in thread "main" java.lang.IllegalStateException: Scanner closed
at java.util.Scanner.ensureOpen(Scanner.java:1115)
at java.util.Scanner.next(Scanner.java:1510)
at java.util.Scanner.nextDouble(Scanner.java:2456)
at StatsDemo.main(StatsDemo.java:51)
Replace inputFile with inputFile2 because it's the Scanner object.
Your Scanner is called inputFile2 not inputFile.
Rename inputFile to inputFile2 in code while (inputFile.hasNext())
Your Scanner object is with inputFile2 and you are using inputFile as a scanner object. I am surprised how is your code running without any compile errors. In case you have another file which is associated with inputFile Scanner object for which you have not provided code above, just check the file and closing of that reference where you are flushing the inputFile object. Otherwise, correct your code as below:
File rf2 = new File("Numbers.txt"); //reconnect to the FileReader object passing it the filename
Scanner inputFile2 = new Scanner(rf2);//reconnect to the BufferedReader object passing it the FileReader object.
sum = 0; //reinitialize the sum of the numbers
count = 0; //reinitialize the number of numbers added
//priming read to read the first line of the file
while (inputFile2.hasNext()) //loop that continues until you are at the end of the file
{
difference = inputFile2.nextDouble() - mean; //convert the line into a double value and subtract the mean
sum += Math.pow(difference,2); //add the square of the difference to the sum
count++; //increment the counter
if (inputFile2.hasNextDouble())
inputFile2.nextLine(); //read a new line from the file
}
inputFile2.close(); //close the input file
stdDev = Math.sqrt(sum/count); //store the calculated standard deviation