Regexp w czytaniu pliku txt - Java

0

Cześć, męczę się z tym od kilku godzin a rozwiązanie jest zapewne banalne...
Mój kod:

        try {
            sc = new Scanner(new File("file.txt")).useDelimiter("\t");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        while (sc.hasNext()) {
            data.add(sc.next());
        }

Chodzi o to, że mam plik textowy w którym zawarte są informacje o piłkarzach i wygląda to na wzór:

Jan Kowalski (tabulator) 20 (tabulator) Napastnik
Paweł Nowak (tabulator) 22 (tabulator) Pomocnik

Chcę wczytać do mojej arraylisty wszystkie te informacje oddzielone tabulatorem czyli: array.get(0) = Jan Kowalski, array.get(3) = Paweł Nowak. Mój kod wyrzuca nullPointerem i nawet pod koniec nie mogę wyświetlić jej rozmiaru. Czy jest to odpowiednie rozwiązanie? Oczywiście spacje mają zawierać się w jednej pozycji, tylko tabulator określa, że będzie to kolejny index. Jak jest z nowymi liniami? Powinno się dodać do Delimitera "\n"? Czy hasNext powinno mieć jakieś ograniczenie i wtedy nie rzucałoby nullPointerem?

Proszę o pomoc.
Pozdrawiam.

0

Podaj wyjątek i sposób tworzenia obiektu dla referencji data. Będzie łatwiej dojść co jest nie tak.

0

Po pierwsze, masz złą koncepcję pamiętania informacji.

class Zawodnik{
    String nazwisko;
    int wiek;
    String pozycja;
    public Zawodnik(String nazwisko, int wiek, String pozycja){
        this.nazwisko = nazwisko;
        this.wiek = wiek;
        this.pozycja = pozycja;
    }
}
...
ArrayList<Zawodnik> dane = new ArrayList<Zawodnik>();

Przypuszczam, że brakowało Ci w kodzie prawej strony i zmienna data miała wartość null.
Po drugie, źle czytasz. Czytaj liniami.

        try {
            sc = new Scanner(new File("file.txt")).useDelimiter("\t");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        while (sc.hasNextLine()) {
            String line = sc.nextLine();
            String[] items = line.split("\\s+");
            dane.add(new Zawodnik(items[0],items[1],items[2]));
        }
0

Bardzo dziękuję za odpowiedź jednak wydaje mi się, że czegoś brakuje bo jak zrobię tak jak napisałeś to przyjmijmy, że moja linijka w pliku jest następująca:

Anna Maria Jopek (tabulator) 25 (tabulator) Pomocnik

Wtedy przy tym kodzie do nowego obiektu trafiają po kolei: Nazwisko - Anna, Wiek - Maria, Pozycja - Jopek. Właśnie to mnie dręczy bo chcę spacje zostawić, zawsze kolejne "dane" będą oddzielane tabulatorem. Gdy sprawdzam coś takiego:

dane.add(new Zawodnik(items[0],items[2],items[3]));

To wyrzuca wyjściem poza array, dlaczego? Przecież nie mam ograniczone ile słów trafia do tablicy items. Nie znajdują się akurat w tym przypadku wszystkie słowa i np w powyższym przykładzie items[4] nie powinno zwracać "Pomocnik"? Jeśli rozumiem split w tym przypadku oddziela spacje (\s+) a nie powinno tabulatorów?

Co do pomysłu zapisywania konkretnego obiektu Zawodnik, super pomysł. W pierwszej chwili na to nie wpadłem a uprości moją pracę tylko pozostaje kwestia wczytywania danych co każdy tabulator z linii.

0

Czy wokół tabulatora mogą być spacje? W pierwszym poście są spacje. Czytanie będzie znacznie prostsze jeśli wokół tabulatora nie będzie spacji. Wtedy powinno wystarczyć

String[] items = line.split("\t+");

\\s+ bierze jako separatory ciągi białych znaków (spacje i tabulatory).

0

Gdy mam teraz tak:

        int counter = 0;
        try {
            sc = new Scanner(new File("test.txt")).useDelimiter("\t");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        while (sc.hasNextLine()) {
            String line = sc.nextLine();
            String[] items = line.split("\t+");
            dane.add(new Zawodnik(items[0],items[1],items[2]));
            counter++;
        }
        System.out.println(counter);

W tym momencie wszystko, cały plik mieści się w items na pozycji 0. Użycie items[1] od razu wyrzuca wyjście za tablicę.
Co do odstępów, możliwe, że nie było to zbyt jasne. Pomiędzy wartościami godność, wiek, pozycja są tylko tabulatory bez żadnych spacji ale np. w godność spacja może wystąpić tak jak we wspomnianym wcześniej przykładzie Anna Maria Jopek czy Jan Kowalski.

Co do powyższej wklejki, w takim razie "useDelimiter" nie jest zbędny jeśli chcemy skorzystać z line split? Mimo, że zakomentuję metodę useDelimeter to arrayIndexOut... dalej występuje.

0

Jesteś pewien, że w pliku test.txt są tabulatory? Z tego, że Ty naciskałeś Tab nie wynika, że w pliku zapisały się tabulatory. Obejrzyj plik hexadecymalnie (jakiś Hex Edytor albo TotalCommander, F3 a potem 3). Powinny być bajty o numerze 9.
useDelimiter jest zbędny.

0

Zrobiłem tak jak mówiłeś, w TC znalazłem przykład 09 bitu i powklejałem tam gdzie tego potrzebowałem i wszystko śmiga. Wielkie dzięki za pomoc. Teraz będę działał sam bo tylko to wczytanie sprawiało problem. Bardzo Ci dziekuję bogdans.

Jeszcze takie pytanko, bo to prawda, sam klikałem "tab" i myślałem, że robi się odpowiedni odstęp. Dlaczego w takim razie nie działa ten sposób tylko w niektórych miejscach robi się te 9 bit a w innych coś innego?

0

Jakiego programu użyłeś by napisać plik test.txt? Ja używam notepad++, a ponieważ nie lubię plików z tabulacją, to zmieniłem preferencje.tab2space.png

0

Treść skopiowałem z html'a, która podobno miała zawierać tabulatory. Potem w IntelliJ bezpośrednio naciskałem tab. Czyli jeśli nie mam zaznaczone "zastąp" spacją i "normal" to notepad powinien ustawiać odpowiednio 9 bajtów?

0

A nie możesz użyj innego, pewniejszego, separatora? Np. średnik jest dobrym kandydatem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1