Почему сканер не переходит на следующую строку при чтении файла? - PullRequest
0 голосов
/ 25 октября 2018

Я использую следующий код для чтения файла:

Scanner fscanner = null;
try {
    fscanner = new Scanner(new File("spotify.txt"));
} catch (FileNotFoundException e) {

    e.printStackTrace();
}

while(fscanner.hasNextLine()) {
    String line = fscanner.nextLine();

    Scanner lineScanner = new Scanner(line);
    Album album = new Album();

    if(lineScanner.next().equals("CD")) {
        album.setComposers(lineScanner.next().replaceAll(",", "'s"));
        album.setAlbumName(lineScanner.useDelimiter(",").next().trim());
        album.setYear(lineScanner.next().trim());
        fscanner.nextLine();

        String c = album.getAlbumName();
        String a = album.getComposers();
        String y = album.getYear();

        System.out.println(a+" "+c+" "+y);

    }
    else if(lineScanner.next().equals("SONGS")) {
        ArrayList<String> songs = new ArrayList<String>();
        ArrayList<String> songDur = new ArrayList<String>();

        lineScanner.nextInt();

        songs.add(lineScanner.useDelimiter(",").next());
        songDur.add(lineScanner.next());

        album.setSongs(songs);
        album.setSongDurations(songDur);

        for(int i=0, j=0;i<songs.size() && j<songDur.size();i++, j++)
            System.out.println("SONG "+i+" "+songs.get(i).toString()+ " "+songDur.get(j).toString());

        System.out.println(album.showSongs());
        System.out.println(album.showSongDurations());

    }
    else if(lineScanner.next().equals("ADD")) {
        Adds adds = new Adds();

        adds.setCompanyName(lineScanner.useDelimiter(",").next().trim());
        adds.setDuration(lineScanner.next());
    }
}

Файл выглядит примерно так:

CDS
CD U2, Songs of Innocence, 2014
SONG 1, The Miracle, 4:15
SONG 2, Every Breaking Wave, 4:12
SONG 3, California, 4:00
SONG 4, Song for Someone, 3:47
CD Coldplay, Parachutes, 2000
SONG 1, Don’t Panic, 2:17
SONG 2, Shiver, 5:00
SONG 3, Spies, 5:19
SONG 4, Sparks, 3:47
SONG 5, Yellow, 4:27
CD ImagineDragons, Night Visions, 2015
SONG 1, Demons, 3:14
SONG 2, Monster, 2:57
ADDS
ADD ING Bank, 0:20
ADD Bol.com, 0:15
ADD Albert Heijn, 0:30
ADD Specsavers, 0:15
ADD Kruidvat, 0:10
ADD MediaMarkt.nl, 0:20

Проблема в том, что я получаю NoSuchElementException встрока else if(lineScanner.next().equals("SONGS")).

Я просто не знаю, почему это происходит, когда код фактически выполняется с переходом на следующую строку, как и должно быть, если я удаляю оба из else-ifs.

Вывод, который он выдает, точно такой, как ожидалось, но не тогда, когда я представляю эти else-ifs.

Как мне это исправить?

Ответы [ 3 ]

0 голосов
/ 25 октября 2018

Сначала уточните у lineScanner, есть ли у него какой-либо элемент для анализа.Затем свяжите возвращаемую переменную lineScanner.next() с новой переменной, чтобы вам не приходилось вызывать lineScanner.next() каждый раз при проверке if-else, потому что этот метод будет переходить к следующему слову при каждом его вызове.Хотя не очень очевидно.

Scanner fscanner = null;
    try {
        fscanner = new Scanner(new File("src/spotify.txt"));
    } catch (FileNotFoundException e) {

        e.printStackTrace();
    }

    while(fscanner.hasNextLine()) {
        String line = fscanner.nextLine();

        Scanner lineScanner = new Scanner(line);

        while(lineScanner.hasNext()){
            //Trim the word
            String word = lineScanner.next().trim();
            System.out.println(word);
        }
    }
    //Do not forget to close it
    fscanner.close();
0 голосов
/ 25 октября 2018

@ Аррон объяснил вам причину.

Теперь, может быть, это поможет мне поверить, что это быстрее и лучше, чем сканер

int count = Files.lines(Paths.get(text_File_Location)).count(); //count number of lines in text file without any loop

 Path path = Paths.get(*text_File_Location, Name or URL*);

               for (int i = 0; i < count; i++) 
               {   
                    //It read exactly what we need
                    String line = Files.readAllLines(path).get(i);

                    //lets say u have data in text file in this format
                    //SONG,MUSIC,YEAR   Separated by comma


                    String everything[] = line.split(",");
                    String song = everything[0];
                    String music = everything[1];
                    String year = everything[2];

               }
0 голосов
/ 25 октября 2018

В первой строке вы собираетесь прочитать первый токен и проверить, равен ли он CD;затем, если это не так, вы попытаетесь прочитать другой токен (из той же строки), чтобы проверить, равен ли он SONGS, что приведет к ошибке в первой строке, так как больше нет токенов для чтения из этой строки.

Вы захотите прочитать первый токен строки в переменную перед вашим if / else if и ссылаться на эту переменную в ваших условиях, чтобы все они проверяли первый токен строки.

В качестве примечания я бы не использовал два разных сканера;если я не ошибаюсь, вы неправильно пропускаете строку в ветке CD при вызове fscanner.nextLine();, что было бы полезно, если бы вы везде использовали один и тот же сканер (чтобы отбросить неиспользуемый остаток строки).В этом случае вызов nextLine должен быть помещен после if / else, чтобы избежать дублирования.

...