views:

117

answers:

3

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?

+1  A: 

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

Alex Hart
+2  A: 

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...
  }
}
Christopher Hunt
Even though I didn't use your suggestion, I still picked your response as the answer since it did send me down on the right track. Thanks!
Jason
Thanks. Another solution to parsing is of course to use ANTLR. There's a learning curve, but worth it depending on your parsing requirements. Its lexer may also serve you well.
Christopher Hunt
+3  A: 

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"

Kevin Zhou