Question

I have a file that contains lots of movie titles along with their years, rating out of 5 stars, and length. I'm attempting to read the file and store the titles, year, rating, and length as variables. The problem I've encountered is in my code for retrieving the year. The code compiles, but then upon running throws a NumberFormatException when it gets to a movie with multiple years (for example, it is listed as 2006-2009). Here is my code.

while((line = bufferedReader.readLine()) != null) {
                //System.out.println(line);
                for(int i = 0; i < line.length(); i++)
                {

                    if(line.charAt(i) == ')' || line.charAt(i) == '-')//get year
                    {
                        yr = line.substring(yearStart,i);
                        year = Integer.parseInt(yr);
                    }

                }
                System.out.println(year);

            }

Shouldn't line.charAt(i) == '-' in my if statement take care of this issue?

EDIT: The below code is where yearStart comes from.

if(line.charAt(i) == '(')//get title
                    {
                        title = line.substring(0,i);
                        yearStart = i+1;
                    }

The file is formatted like this: title (year) | rating, length Sorry, I should have included that originally.

EDIT #2: Here's a sample of part of the file, if that helps

!Women Art Revolution (2010) |   3 stars, 1hr 22m
#1 Cheerleader Camp (2010) |   3 stars, 1hr 35m
$5 a Day (2008) |   3.4 stars, 1hr 37m
'night, Mother (1986) |   3.7 stars, 1hr 36m
'Til Death (2006-2009) |   3.7 stars, 4 Seasons//This is the one that causes the error
@Suicide Room (2011) |   3.4 stars, 1hr 51m
... And God Spoke (1993) |   2.8 stars, 1hr 22m
Was it helpful?

Solution

What happens once you have found the year? The loop will still run until the end of the line, trying to parse things as numbers every time it finds a ) or a -.

Maybe you should exit the loop once you have found the year.

                if(line.charAt(i) == ')' || line.charAt(i) == '-')//get year
                {
                    yr = line.substring(yearStart,i);
                    year = Integer.parseInt(yr);
                    break; // year found, no point in looping more
                }

Or maybe you should reset the yearStart index so that the second year can be parsed.

                if (line.charAt(i) == '-')
                {
                    // parse first year
                    yr = line.substring(yearStart,i);
                    year = Integer.parseInt(yr);
                    yearStart = i + 1; // reset to parse second year
                }
                else if (line.charAt(i) == ')')
                {
                    yr = line.substring(yearStart,i);
                    year = Integer.parseInt(yr);
                    break; // year found
                }

OTHER TIPS

Put Intger.parseInt in a try/catch block (similar to the one below) to see where this is failing and how:

try { 
  year = Integer.parseInt(yr);
} catch (Exception e) {
  throw new RuntimeException(
      "Failed to parse year '" + yr + "' in line '" + line + "'", e);
}

Btw: line.indexOf(')') returns the position of '(' in line.

After the first year is found, yearStart is still at the index of the first year. So when you try and get a subString, it is still (2006-2009) - Automatic NumberFormatException, can't parse the -.

You should change the yearStart after the first year is found:

for(int i = 0; i < line.length(); i++)
{

    if(line.charAt(i) == ')' || line.charAt(i) == '-')//get year
    {
          yr = line.substring(yearStart,i);
          year = Integer.parseInt(yr);
          yearStart = i + 1;
    }

}

The condition if(line.charAt(i) == ')' || line.charAt(i) == '-') holds true twice in your loop. First, when the hyphen matches, and then, when the closing parenthesis matches. The first time, year is assigned to, in your example, 2009. But then, the loop keeps running, and a few iterations later, you try to parse "2005-2009" which results in the NumberFormatException.

The most straightforward solution is to break; the loop just after assigning year, so that year is only assigned once. That said, supposing that you want to get the starting value of the interval.

A cleaner solution would be to avoid the loop at all, and instead judiciously using String.indexOf. Something like that (disclaimer: untested).

String title;
int year;

while((line = bufferedReader.readLine()) != null) {

    title = line.substring(0, line.indexOf('('));

    int yearStart = line.indexOf('(') + 1;
    int yearEnd;
    if (line.indexOf('-', yearStart) > 0 ) {
        yearEnd = line.indexOf('-', yearStart);
    } else {
        yearEnd = line.indexOf('(', yearEnd);
    }

    int yr = line.substring(yearStart,i);
    year = Integer.parseInt(yr);

    System.out.println(year);
}

Finally, a more professional solution would use regular expresions, I understand you might not be familiar with that, and thus I have tried to provide an answer that follows a similar structure as yours.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top