Tokenizacja stringów

Dyskusje na temat Javy.
rhymie
Początkujący
Początkujący
Posty: 11
Dołączył(a): wtorek, 29 września 2009, 11:04

Tokenizacja stringów

Post przez rhymie »

Witam, jestem tu pierwszy raz.

Interesuje mnie odczyt z pliku danych rozdzielonych ","
zrobiłem sobie taki programik, ale nie wiem jak zrobić aby nie wywalało błędu gdy token będzie pusty.

moje dane w pliku to np.

aaaa,bbbb,cccc,dddd,eeee - dla takich danych ładnie czyta, ale dla:
aaaa,bbbb,,dddd,eeee - już wywala błąd.

czytałem w dokumentacji że trzeba obsłużyć wyjątek "NullPointerException" - ale jak to zrobić ?

-------------------------
moja klasa:

Code: Zaznacz cały

public static Towar[] odczytajZPliku(BufferedReader inS) throws IOException
    {
        int dl = 5;
        Towar[] towar = new Towar[dl];
        
        for (int i = 0; i < dl; i++)
        {
            String linia = inS.readLine();
            StringTokenizer tokeny = new StringTokenizer(linia, ",", false);

                String nr_czesci = tokeny.nextToken();
                String nazwa = tokeny.nextToken();
                String ilosc = tokeny.nextToken();
                String material = tokeny.nextToken();
                String norma = tokeny.nextToken();
                String producent = tokeny.nextToken();
                        
            towar[i] = new Towar(nr_czesci, nazwa, ilosc, material, norma, producent);
         }
}
-----------------------------
Edited: Użwaj znaczników code
Morfidon
Administrator
Administrator
Posty: 1332
Dołączył(a): wtorek, 5 sierpnia 2008, 21:48
Contact:

Re: Tokenizacja stringów

Post przez Morfidon »

Witam,

Zwracanie wyjątków oraz ich obsługiwanie są dokładnie omówione w pierwszym kursie Javy. Służy do tego konstrukcja try{ } catch(){}...

Jednak w tym wypadku lepiej zrobić to inaczej, są co najmniej 2 proste rozwiązania.

Jedno z nich to zapisywanie pustych danych do pliku jako np. spacja, czyli zamiast:

aaaa,bbbb,,dddd,eeee

zapisywać je tak:

aaaa,bbbb, ,dddd,eeee .

Wersja dłuższa

Code: Zaznacz cały

                    String nr_czesci = tokeny.hasMoreTokens()? tokeny.nextToken(): null;
                    String nazwa =tokeny.hasMoreTokens()?  tokeny.nextToken(): null;
                    String ilosc =tokeny.hasMoreTokens()?  tokeny.nextToken(): null;
                    String material = tokeny.hasMoreTokens()? tokeny.nextToken(): null;
                    String norma =tokeny.hasMoreTokens()?  tokeny.nextToken(): null;
                    String producent =tokeny.hasMoreTokens()?  tokeny.nextToken(): null;
Pozdrawiam,

Arkadiusz
rhymie
Początkujący
Początkujący
Posty: 11
Dołączył(a): wtorek, 29 września 2009, 11:04

Re: Tokenizacja stringów

Post przez rhymie »

Witaj, dzięki za odpowiedź.

Plik źródłowy mam utworzony z innego programu, więc zapisywanie do niego nie wchodzi w grę.
Właśnie o coś takiego jak Twoja dłuższa wersja mi chodziło, tylko, że nie do końca to działa w moim przypadku.

Twoje rozwiązanie pozwala pominąć brak tokena i na końcu wstawić null,
u mnie trzeba w miejscu gdzie nie ma tokena wstawić null (lub " "), gdyż kolumny muszą się zgadzać.


P.S. docelowo program ma ładować dane do bazy więc musze zadbać o kolumny.
Morfidon
Administrator
Administrator
Posty: 1332
Dołączył(a): wtorek, 5 sierpnia 2008, 21:48
Contact:

Re: Tokenizacja stringów

Post przez Morfidon »

No to zmień:

Code: Zaznacz cały

String nr_czesci = tokeny.hasMoreTokens()? tokeny.nextToken(): null;
na:

Code: Zaznacz cały

String nr_czesci = tokeny.hasMoreTokens()? tokeny.nextToken(): " ";
rhymie
Początkujący
Początkujący
Posty: 11
Dołączył(a): wtorek, 29 września 2009, 11:04

Re: Tokenizacja stringów

Post przez rhymie »

oczywiśnie że tak też próbowałem, to nie zadziała tak jak chcę,
po prostu pomija to miejsce gdzie nie ma token a jest tylko kolejny separator, i odczytuje kolejny token, a nasze null lub " " dodaje na końcu.

rhymie
Morfidon
Administrator
Administrator
Posty: 1332
Dołączył(a): wtorek, 5 sierpnia 2008, 21:48
Contact:

Re: Tokenizacja stringów

Post przez Morfidon »

Hmm można by użyć klasy Scanner, ale StringTokenizer jest troszeńkę szybszy, więc fajnym wyjściem będzie podmienić linie przed wysłaniem jej do tokenizacji ;)

Code: Zaznacz cały

  
                 if (linia.startsWith(","))
                    linia = linia.replaceFirst(",", " ,");
                if(linia.endsWith(","))
                    linia = linia.concat(" ");
                while (linia.indexOf(",,") != -1)
                    linia = linia.replace(",,", ", ,");
i teraz powinno działać nawet dla takich danych:

Code: Zaznacz cały

aaaa,,cccc,ss ,eeee, fffff
,,,,,
rhymie
Początkujący
Początkujący
Posty: 11
Dołączył(a): wtorek, 29 września 2009, 11:04

Re: Tokenizacja stringów

Post przez rhymie »

To teraz działa wyśmienicie. Dziękuje bardzo.
Post Reply