Pokaż wyniki 1 do 10 z 22

Temat: [Perl]wczytywanie liczb do tablicy

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1

    Domyślnie [Perl]wczytywanie liczb do tablicy

    Mam plik.txt z danymi odzielonymi przecinkami:
    12,34,56
    23,4,5
    12,3,4
    123,1,1

    Chcialbym wczytac te dane do tablicy, tak aby moc sie odwloywac do odpowiedniego elementu, np. chce wyciagnac trzeci element z drugiego wiersza, czyli 5.

    Wczytalam dane z pliku i podzielilam je wg przecinka:
    Kod:
    open (K, 'plik.txt'); while (<K>) {
       $line = $_;
       @d = split(',',$line);
       push(@date,@d);
    }
      close(K);
    
      print @date;
    Niestety nie wiem co dalej mam zrobic, by uzyskac moj zaplanowany cel.
    tzn nie wiem jak sie odwolac do tej tablicy. Czy moge prosic o jakies wskazowki?
    Ostatnio edytowane przez Gosik : 01-10-2013 - 20:03

  2. #2

    Domyślnie

    Troche poprawilam swoj kod.

    Kod:
    open (K, 'plik.txt'); while (<K>) {
       chomp;
       $line = $_;
       @d = split(',',$line);
       push @date,\@d;
    }
      close(K);
    
      print @date;
      print $date[0]->[2];
    Kod ten powoduje, ze mam wyswietlony trzeci element z ostatniego wiersza.

    Co w tym kodzie mam zle? Dlaczego nie wyswietla mi elementu z drugiego wiersza i trzeciej kolumny?

  3. #3
    Zarejestrowany
    Jun 2006
    Skąd
    rand(.eu)
    Postów
    8,748

    Domyślnie

    Do debugowania kodu jesli nie jestes pewna jak wygladaja Twoje dane, swietnie spisuje sie takie cos...

    Kod:
    use Data::Dumper;
    print Dumper \@data;
    teraz mozesz zobaczyc jak wygladaja tablice, hashe i jedno zapakowane w drugie przez referencje... bez tego modulu zginalbym wiele razy a tak chwila, jeden print i juz wiem co jest co.

    Kod:
    print Dumper \$data[0];
    Juz wiesz jak wyglada pierwszy wiersz - powinna byc tablica

    BTW, uzycie referencji tak jak to robisz uzyskujac tablice tablic, to jest podstawa w dalszym obiektowym programowaniu w Perlu - to tak jak pointer w C. Zalety sa ogromne:
    1. nie kopiujesz danych przekazujac je do funkcji jako parametry tylko przekazujesz wskaznik odwolujacy sie do oryginalnej zmiennej
    2. mozesz przekazywac zmienne o innym zakresie leksykalnym, ktore normalnie nie istnialyby w tym segmencie kodu - przekazywanie wartosci normlanie i zbieranie wynikow byloby bardzo trudne w wiekszym projekcie i podatne na wystapienie glupich bledow (wiem bo sam sie na to nie raz zlapalem)
    3. uzywajac modulow ktore uzywaja zapisu obiektowego, Twoje obiekty nie sa niczym innym jak referencje

    nie martw sie tym co napisalem wyzej - wazne jest to ze idziesz w dobrym kierunku a do tych 3 elementow dojdziesz sama we wlasnym czasie
    ctrl-alt-del.cc - soft reset site for IT admins and other staff :-)

  4. #4

    Domyślnie

    [QUOTE=TQM;62239]Do debugowania kodu jesli nie jestes pewna jak wygladaja Twoje dane, swietnie spisuje sie takie cos...

    Kod:
    use Data::Dumper;
    print Dumper \@data;
    Wielkie dzieki za te info.

    Teraz wiem w czym tkwi problem. Mianowicie do kazdej tablicy jest wczytywany oststni wiersz.
    Tylko nie wiem dlaczego...

    Moze widzisz dlaczego tak sie dzieje i gdzie jest moj blad w rozumowaniu?

  5. #5
    Zarejestrowany
    Jun 2006
    Skąd
    rand(.eu)
    Postów
    8,748

    Domyślnie

    To nie blad w rozumowaniu :-)

    Kod wyglada ok ale nie dziala. Moge jedynie zgadywac, ze chodzi o to, ze odkladasz do @date referencje do globalnej zmiennej @d, globalnej i deklarowanej wewnatrz petli... jak teraz przepiszesz wartosc zmiennej wczytujac nastepny wiersz, to zmieniasz to co juz odlozylas do @date :-)

    Piszac w perlu warto dodac dwa moduly, strict i warnings. Strict nie pozwoli na takie luzne deklarowanie zmiennych, trzeba je zadeklarowac uzywajac my, our albo local. Generalnie pomaga to w sledzeniu zasiegu zmiennych i znajdywaniu literowek w kodzie, bo program od razu poda ze uzywasz nieznanej zmiennej. Uzycie warnings dodatkowo daje informacje o tym, ze np zmienna ktorej uzywasz jest undef, czyli logika skryptu bedzie wariowac bo szukasz wartosci aby wstawic do zmiennej, wszystko wyglada dobrze a skrypt nie dziala... bo zmienna jest undef bo albo dane byly nieprawidlowe albo regex zle zapisany albo cos innego. Warnings ostrzega tez, jesli w ramach jednego bloku {} ponownie deklarujesz zmienna o tej samej nazwie.

    Ogolnie aby pisac w Perlu i nie popelniac bledow warto od poczatku zapamietac:
    Kod:
    use strict;
    use warnings;
    Kazdy moj skrypt od tego sie zaczyna, no chyba ze jest to 1-linijkowiec odpalany prosto z wiersza polecen :-) W kazdym innym wypadku mam te dwa moduly.

    Poprawiona wersja kodu wyglada tak:
    Kod:
    #!usr/bin/perl
    use Data::Dumper;
    use strict;
    use warnings;
    
    my @date;
    open (K, 'plik.txt'); 
    while (<K>) {
       chomp;
       my @d = split(/,/);
       push @date,\@d;
    }
    close(K);
    print Dumper \@date;
    a wynik dzialania taki:
    Kod:
    $VAR1 = [
              [
                '12',
                '34',
                '56'
              ],
              [
                '23',
                '4',
                '5'
              ],
              [
                '12',
                '3',
                '4'
              ],
              [
                '123',
                '1',
                '1'
              ]
            ];
    ctrl-alt-del.cc - soft reset site for IT admins and other staff :-)

  6. #6

    Domyślnie

    Swietnie! Bardzo dziekuje za pomoc, juz jest jakis progress

    Dzialam dalej i nasunelo mi sie jescze jedno pytanie.

    Mam dwa pliki z danymi:
    plik1.txt
    4,11,23,1
    5,33,44,2
    6,44,55,2

    plik2.txt

    1,23,4
    2,334,43
    3,44,5
    4,55,6
    5,33,4

    Porownuje pierwsze wyrazy z pliku i jesli sa takie same, wrzucam do tablicy.
    Daze do tego by otrzymac plik3.txt w nastepujacej postaci:
    4,11,23,1,4,55,6
    5,33,44,2,5,33,4

    stworzylam taki kod:
    Kod:
    my @tab;
     for (my $i=0; $i<=$#date; ++$i){
       if ($date[$i]->[0] = $date2[$i]->[0]){
        my @b = ($date[$i],$date2[$i]);
         push @tab, \@b;
    #     push @tab,\@date2[$i]; 
        }
      }
    
     print $tab[0]->[1][2];

    Moje pytanie brzmi:
    jak poprawnie powinnam sie odwolywac do tablicy @tab?
    Jak widac probowalam to uczynic w nastepujacy sosob:
    Kod:
    print $tab[0]->[1][1]
    Ale niestety nie jest to poprawne.

    Czy w tej kwestii moglabym rowniez liczyc na wskazowke?

Zasady Postowania

  • Nie możesz zakładać nowych tematów
  • Nie możesz pisać wiadomości
  • Nie możesz dodawać załączników
  • Nie możesz edytować swoich postów
  •  
Subskrybuj