Jason
Jason

Reputation: 11363

Parsing a text file in Java

Example from input file:

ARTIST="unknown"
TITLE="Rockabye Baby"
LYRICS="Rockabye baby in the treetops
When the wind blows your cradle will rock
When the bow breaks your cradle will fall
Down will come baby cradle and all
"

The Artist, Title & Lyrics fields have to be extracted to their respective Strings with captalization and format unchanged. This code for the Artist field

while (readIn.hasNext()) {
    readToken= readIn.next();
    if (readToken.contains("ARTIST")) {
        artist= readIn.next();
        }
        if (readToken.contains("TITLE")){
            title= readIn.next();
    System.out.print(artist+" "+title);
}

ends up printing this out:

"unknown"
TITLE null"unknown"
TITLE null"unknown"
TITLE

From the code, I can't see why the output is printing this way. For every time through the loop, the readToken string gets refreshed, and should then be compared by the contains() method. Obviously I'm missing something here.

So, am I close to the right track or am I in a completely different city?

Upvotes: 1

Views: 1673

Answers (3)

Kevin Zhou
Kevin Zhou

Reputation: 1283

From your code of

while (readIn.hasNext()) {
    readToken= readIn.next();
    if (readToken.contains("ARTIST")) {
        artist= readIn.next();
        }
    if (readToken.contains("TITLE")){
        title= readIn.next();
    System.out.print(artist+" "+title);
}

The program, if assuming is declared and instantiated correctly (the variables artist, readToken and title) is firstly checking if there exists an existing next line in the while condition, if that is true, the String (im assuming) readToken is saved as the next line. If readToken contains "ARTIST", then the NEXT line down is saved as the artist string. Likewise for containing "TITLE". By the time the while loop repetends, you might have already hit LYRICS, skipping the TITLE altogether, causing it to be NULL.

What you want is maybe saving

artist = readToken; or title = readToken; instead.

Also don't forget to substring artist and title if you don't want a print of "ARTIST="ARTISTNAMEHERER" TITLE="TITLENAMEHERE"" and rather "ARTISTNAME, TITLENAME"

Upvotes: 3

Christopher Hunt
Christopher Hunt

Reputation: 2081

Further to Alex Hart's answer, I think you might consider using Java's Pattern and Matcher classes and use groups to obtain the matched arguments e.g. (non tested):

private static final Pattern RECORDING_HEADER = 
  new Pattern("(ARTIST=\\"(.*)\\")?(TITLE=\\"(.*)\\")?(LYRICS=\\"(.*)\\")?");

Then when you're reading a line:

String line = readIn.readLine(); // Presuming that readIn is a BufferedReader
Matcher m = RECORDING_HEADER.matcher(line);

if (m.matches()) {
  final int artistGroup = 2;
  String artist = m.group(artistGroup);

  final int titleGroup = 4;
  String title = m.group(titleGroup);

  final int lyricsGroup = 6;
  String lyrics = m.group(lyricsGroup);

  if (artist != null) {
    // You've got an artist...
  } else if (title != null) {
    // etc...
  }
}

Upvotes: 2

Alex Hart
Alex Hart

Reputation: 1673

It looks as if what you are doing here is reading in line by line, but when you find what you are looking for, you are setting your variable to the next line. This may be causing issues and out of bounds problems, and could very well be a symptom of your mishap

Upvotes: 1

Related Questions