FileScanner does not have the next Line for Txt Files With First Few Lines Starting with Integers Concatenated with Strings

41 Views Asked by At

I am trying to use file scanner in Java to read a txt file and populate a linked list with parse information from the file. The file is tab delimited and needs to get the "name" and "console". The file that does not work is accessable here: https://drive.google.com/file/d/1dagU0W_zsAlojfJnU55c-vQNdZF6sYxB/view?usp=sharing. Where it does not ever have the next line and immediately exits the while loop. If I move the first four items to the bottom of the txt file as in this file: https://drive.google.com/file/d/1430Pw4dGy3VT0BGfKzXnltiKud_427Ib/view?usp=sharing.

it works fine. I am using hasNextLine(). Please tell me if there is something obvious I am overlooking.The code is below:

   try{
        File file = new File(fileName);
   
        Scanner fileScanner = new Scanner(file);

        int nameCol = 0;
        int consoleCol = 1;
        //FILESCANNER DOES NOT HAVE THE NEXT LINE
        // if(!(fileScanner.hasNextInt()||fileScanner.hasNextLine()))
        //     System.out.println("filescanner does not have next line");

        //won't work skips over while loop
        while(fileScanner.hasNextLine())
        {
             String line = fileScanner.nextLine();
            
             if(line!=""){
                     String[] items = line.split(DELIM);
                     if(items.length==COLS){
                       String name = items[nameCol];
                       String console = items[consoleCol];

                       VideoGame temp = new VideoGame(name,console);
                       games.add(temp);
                     }
             }
         }
         fileScanner.close();
    }catch(FileNotFoundException e){
        e.printStackTrace();
        System.exit(1);
    }

I tried using hasNextInt()||hasNextLine() within the while loop. I also know that the system recognizes that the file exists. I apologize for any messy code, as I am new to this. Again, note that the code functions fine with the numerical starting lines at the bottom. Unfortunately, I cannot simply keep the file rewritten and must use the original file as formatted. The full src code is available at:

https://drive.google.com/file/d/1J9KThbM3_ZwF4ZxV7o0vMy7JN03ifrTP/view?usp=sharing (most relevant, contains bad method at around line 142)

https://drive.google.com/file/d/15jwqa8V3m83dgxMGW6C80cGjCaJMv6W9/view?usp=sharing (contains linked list I am using to store parsed data)

https://drive.google.com/file/d/1ejiSfejIP74m27lagay5RwVrDWdY_vQg/view?usp=sharing (class for storing data)

1

There are 1 best solutions below

1
g00se On

It can often be a bad plan to do your own CSV parsing in Java as it's error prone, so better to use a library. If, however, your files are simple then you might try it yourself when doing exercises. If you've got a tab-delimited file such as this (unfortunately this site has converted the tabs to four spaces, hence my comment above about posting a link):

"Addams Family, The"    Nintendo Entertainment System [US]
Adventure   Atari 2600 [NA]
"Adventures of Bayou Billy, The"    Nintendo Entertainment System [US]
"Adventures of Rad Gravity, The"    Nintendo Entertainment System [US]
Airwolf Nintendo Entertainment System [US]
Anticipation    Nintendo Entertainment System [US]
Armor Ambush (Black Label)  Atari 2600 [NA]

then you can use your Scanner to deal with this.* Simplify the problem with a special 'valueOf' method in your bean to deal with CSV, here VideoGame::valueOfCsv so you can create it easily from text:

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Scanner;

public class VideoGameReader {
    public static void main(String[] args) throws Exception {
        try (Scanner s = new Scanner(Files.newBufferedReader(Path.of(args[0]))).useDelimiter("\t|\\R")) {
            while(s.hasNextLine()) {
                System.out.println(VideoGame.valueOfCsv(s.nextLine(), "\t"));
            }
        }
    }
}

This gives the following output with the above file:

name="Addams Family, The",console=Nintendo Entertainment System [US]
name=Adventure,console=Atari 2600 [NA]
name="Adventures of Bayou Billy, The",console=Nintendo Entertainment System [US]
name="Adventures of Rad Gravity, The",console=Nintendo Entertainment System [US]
name=Airwolf,console=Nintendo Entertainment System [US]
name=Anticipation,console=Nintendo Entertainment System [US]
name=Armor Ambush (Black Label),console=Atari 2600 [NA]
  • (Of course you will note that changing the default delimiters of the Scanner is redundant if your bean is taking care of the CSV but I changed it for illustrative purpose)