Parsing a text file string by string in java - java

So I'm having a problem with parsing a text file. Let's say I have a text file with contents like this(all strings are separated by a space and all lines after line 1 only contain 2 strings):
a b c d e
a b
c d
I need to process the first line one string at a time. That is "a"(then use a for a method) then "b"(use b for a method) and so on.
After this, I need to process lines 2 and 3 in a different way. Read line 2, store "a" in a variable as e1, then process "b" and store b in a variable e2. Then I need to use e1 and e2 for a separate method. All lines after line 1 do the same thing as I just described.
My problem is that my code is just reading the whole line and storing that as the variables. Thus, I'm not reading each individual string. Also, I don't understand how to tell when I'm done processing line 1(this is important because I use a different method for all lines after line 1). Here's what I have:
Scanner scan = new Scanner(new File(args[0]));
while(scan.hasNext()){
String input = scan.nextLine();
t.addV(input);
}
while(scan.hasNext()){
String e1 = scan.next();
String e2 = scan.next();
t.addE(e1, e2);
}
I know this is very wrong but I'm just looking to understand how I would know when I'm done reading line 1 and how I would just read each individual string.

You are really close, just a couple things off.
Step 1: getting the first line and calling a method for each individual letter
String firstLine = scan.nextLine();
// splits the line into a letter array
String[] letters = firstLine.split("\\s");
for(String letter: letters){
// do your method
}
Step 2: Getting the two individual letters and calling methods depending on the letter:
while(scan.hasNextLine()){
String line = scan.nextLine();
String[] lets = line.split("\\s");
String e1 = lets[0];
String e2 = lets[1];
// do your methods with the individual letters
}
You could of course use scan.next() to retrieve one letter at a time, but it seems by the way you worded your question that the line that the letters are on is needed knowledge to the method call. Which is why I've also assumed that there are a maximum of two letters per line on subsequent lines.

I recommend you using an BufferedReader, to read a file line by line
try (BufferedReader reader = new BufferedReader(new FileReader(args[0]))) {
String firstLine = reader.readLine();
//Process with the first line
String secondLine = reader.readLine();
//Process with the second line
} catch (Exception ex) {
}
Edit
To get the elements within a line, use the String.split(String delimiter) method.
Like this:
String[] splittedElements = line.Split(" ");

Related

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
}
}

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);

How do you read a text file, line by line, and separate contents of each line in Java?

I was wondering how to go about reading a file, and scanning each line, but separating the contents of each line into a Char variable and into a Double variable.
Example:
Let's say we write a code that opens up text file "Sample.txt". To read the first line you would use the following code:
while(fin.hasNext())
{
try{
inType2 = fin.next().charAt(0);
inAmount2 = fin.nextDouble();
}
This code basically says that if there is a next line, it will put the next char into inType2 and the next Double into inAmount2.
What if my txt file is written as follows:
D 100.00
E 54.54
T 90.99
How would I go about reading each line, putting "D" into the Char variable, and the corresponding Double or "100.00", in this example, into its Double variable.
I feel like the code I wrote reads the following txt files:
D
100.00
E
54.54
T
90.99
If you could please provide me with an efficient way to read lines from a file, and separate according to variable type, I'd greatly appreciate it. The Sample.txt will always have the char first, and the double second.
-Manny
Use BufferedReader to read line, and then split on whitespace.
while((line=br.readLine())!=null){
String[] arry = line.split("\\s+");
inType2 = arry[0];
inAmount2 = arry[1];
}
You can delimit by whitespace and
Scanner scanner = new Scanner(new File("."));
while (scanner.hasNext()) {
//If both on different lines
c = scanner.next().charAt(0);
d = scanner.nextDouble();
//if both on same line
String s = scanner.next();
String[] splits = s.split("\\s+");
if (splits.length == 2) {
c = splits[0].charAt(0);
d = Double.parseDouble(splits[1]);
}
}
scanner.close();

Java Array Index Out of Bound

I have the following code that reads through a line of students and the program should split at each white space then go to the next part of the text but I get arrayindexoutofBound exception.
The text file has several lines like this:
130002 Bob B2123 35 34 B2132 34 54 B2143 23 34
public static void main(String[] args) throws FileNotFoundException {
File f = new File("C:\\Users\\Softey\\Documents\\scores.txt");
Scanner sc = new Scanner(f);
List<MarkProcessing> people = new ArrayList<MarkProcessing>();
while(sc.hasNextLine()){
String line = sc.nextLine();
String[] details = line.split("\\s+");
String regNumber = details[0];
String name = details[1];
String modOne= details[2];
int courseM = Integer.parseInt(details[3]);
int examM = Integer.parseInt(details[4]);
String modTwo = details[5];
int courseM2 = Integer.parseInt(details[6]);
int examM2 = Integer.parseInt(details[7]);
String modThree = details[8];
int courseM3 = Integer.parseInt(details[9]);
int examM3= Integer.parseInt(details[10]);
MarkProcessing p = new MarkProcessing(regNumber, name, modOne,courseM, examM, modTwo,courseM2,examM2, modThree, courseM3, examM3);
people.add(p);
}
}
}
When it goes to details[1] I get the index error.
Without information regarding the input file, I am going to guess this is because of blank lines in your file. If this is the case, you should try something to ensure that you have enough pieces.. For this, your while loop could be something like this.
while(sc.hasNextLine()){
String line = sc.nextLine();
String[] details = line.split("\\s+");
if(details.length < 11) continue; // skip this iteration
...
}
Keep in mind this is only going to work if you are checking at least 11 items per line. If you need a more advanced method of parsing the input, whereas they may have any number of courses. You are better off thinking of another approach than simply storing values directly from indices.
You should try printing the line before parsing it so that you can see what causes it to blow up.
String line = sc.nextLine();
String[] details = line.split("\\s+");
String regNumber = details[0];
String name = details[1];
String modOne= details[2];
You are splitting on chunks of spaces. In the event you encounter a line with no spaces, then there will only be a single element and therefore details[1] will throw an IndexOutOfBoundsException.
My suggestion is to examine your input carefully. Does it have at trailing line feed? If so, that may be interpreted as a blank line
130002 Bob B2123 35 34 B2132 34 54 B2143 23 34
<blank line>
To split by space, you need to use:
String[] details = line.split(" "); // "\\s+" -> does not split by space.
In your case, it is trying to split the line by the regex pattern '//s+' and since this is not found, it considers the whole line to be one string. In this case, the size of the string array is 1. There is no details[1] and hence you get this error.

My output is assuming the whole file is one line

public static void main(String args[]) throws FileNotFoundException
{
String inputFileName = "textfile.txt";
printFileStats(inputFileName);
}
public static void printFileStats(String fileName) throws FileNotFoundException
{
String outputFileName = "outputtextfile.txt";
File inputFile = new File(fileName);
Scanner in = new Scanner(inputFile);
PrintWriter out = new PrintWriter(outputFileName);
int lines = 0;
int words = 0;
int characters = 0;
while(in.hasNextLine())
{
lines++;
while(in.hasNext())
{
in.next();
words++;
}
}
out.println("Lines: " + lines);
out.println("Words: " + words);
out.println("Characters: " + characters);
in.close();
out.close();
}
I have a text file containing five lines
this is
a text
file
full of stuff
and lines
The code creates an output file
Lines: 1
Words: 10
Characters: 0
However, if I remove the capability for reading the number of words in the file, it correctly states the number of lines (5). Why is this happening?
Your inner while loop is gobbling up the whole file. You want to count the number of words in each line, right? Try this instead:
while (in.hasNextLine())
{
lines++;
String line = in.nextLine();
for (String word : line.split("\\s"))
{
words++;
}
}
Note that splitting on spaces is a very naive approach to tokenization (word-splitting) and will only work for simple examples like the one you have here.
Of course, you could also do words += line.split("\\s").length; instead of that inner loop.
in.hasNext() and in.next() treat all whitespace characters as word separators, including newline characters. Your inner loop is eating all the newlines as it's counting all the words.
This reads next Token, not the line :
in.next();
So it just read next and next and next and dont care about line ending. Space or \n is considered as white space usually, so methods like this one does not make any difference between them.
The reason is, that hasNext() does not care about line breaks.
So, you are entering the while(in.hasNextLine()) loop, but then you are consuming the whole file with the while(in.hasNext()) loop, resulting in 1 line and 10 words.
-> Check the token consumed by hasNext() for EOL-Characters, then increase line count.
OR:
Use String line = scanner.nextLine() to obtain exactly ONE line, and then use a second scanner to fetch all tokens of that line: scanner2 = new Scanner(line); while(scanner2.hasNext())

Categories

Resources