Nowe posty

xx Problem ze sterownikami. (5)
2024-04-13, 21:25:16
xx Instalacja xfce4 (2)
2024-04-13, 16:20:17
xx Serie kompilacji bez instalacji dla “emerge” w Gentoo (2)
2024-04-08, 18:40:04
xx Plasma 6 w Neonie ssie trochę mniej ... (17)
2024-04-05, 10:03:46
xx Problem z Linux Lite po instalacji (3)
2024-04-03, 14:23:40
xx Jak właczyć num locka przy starcie systemu debian 12? (12)
2024-04-02, 17:43:54
xx Brak dźwieku w systemie. (5)
2024-04-02, 16:13:41
xx Dystrybucja pod HP Omen (7)
2024-03-29, 11:33:05
xx [Poradnik] Wyszukiwanie Sterowników (2)
2024-03-27, 21:08:23
xx Ile pingwinów? (1)
2024-03-27, 08:59:24

Autor Wątek: [Perl] wczytywanie liczb z pliku do tablicy  (Przeczytany 6059 razy)

Gosik

  • Gość
[Perl] wczytywanie liczb z pliku do tablicy
« dnia: 2013-01-11, 13:44:44 »
Mam plik.txt z danymi odzielonymi przecinkami:
12,34,56
23,4,5
12,3,4
123,1,1

Chcialabym wczytac te dane do tablicy, tak aby moc sie odwloywac do odpowiedniego elementu,

Wczytalam dane z pliku i podzielilam je wg przecinka:
open (K, 'plik.txt'); while () {
   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?

xavery

  • Gość
[Perl] wczytywanie liczb z pliku do tablicy
« Odpowiedź #1 dnia: 2013-01-14, 12:05:18 »
No cóż... co jest źle? Właściwie wszystko poza otwieraniem pliku:) Nawet konstrukcja pętli jest nieskończona (brakuje w argumentach while()).

Na początek żelazna zasada: używaj 'use strict' i deklaruj zmienne. O wiele łatwiej byłoby czytać taki kod. Poza tym warto używać modułu Data::Dumper i patrzeć jaką strukturę danych uzyskaliśmy. Zakładając, że w pętli while czytamy handler K to otrzymujemy:

use Data::Dumper;
...
   print Dumper @date;
i wychodzi nam na koniec:

$VAR1 = [
          '123',
          '1',
          '1'
        ];
$VAR2 = $VAR1;
$VAR3 = $VAR1;
$VAR4 = $VAR1;
Czyli tablica referencji które praktycznie mają wspólny cel - ostatni wiersz w pliku.
A dzieje się tak dlatego, że do tablicy @date dopisujesz w każdym kroku iteracji niezmienną referencję do tablicy której sama zawartość się zmienia. Aby to wyeliminować należy odkładać w tablicy @date referencje zawierające kolejne wiersze plików a więc zamiast:

   @d = split(',',$line);
   push @date,\\@d;
damy to:

   push @date,[split(',',$line)];
i otrzymujemy taką strukturę:

$VAR1 = [
          '12',
          '34',
          '56'
        ];
$VAR2 = [
          '23',
          '4',
          '5'
        ];
$VAR3 = [
          '12',
          '3',
          '4'
        ];
$VAR4 = [
          '123',
          '1',
          '1'
        ];
Wtedy element $date[0]->[2] będzie tym czym oczekiwaliśmy czyli 56.

xavery

  • Gość
[Perl] wczytywanie liczb z pliku do tablicy
« Odpowiedź #2 dnia: 2013-01-14, 12:14:36 »
Jak już mamy rozwiązanie to dopiszę się tylko, że do takich celów nie trzeba pętli. Handler pliku w kontekście listowym zwraca przecież liste wierszy pliku. Po dodaniu niewielkiej ilości perlowej magii możemy uzyskać taką samą strukturę danych w jednej linijce:

my @date=map {chomp $_; [split ",",$_]} ;

$VAR1 = [
          '12',
          '34',
          '56'
        ];
$VAR2 = [
          '23',
          '4',
          '5'
        ];
$VAR3 = [
          '12',
          '3',
          '4'
        ];
$VAR4 = [
          '123',
          '1',
          '1'
        ];

Gosik

  • Gość
[Perl] wczytywanie liczb z pliku do tablicy
« Odpowiedź #3 dnia: 2013-01-17, 07:40:44 »
Bradzo dziekuje za pomoc! :)

Jednakze mam jeszcze jeden problem:

Mam 2 pliki z danymi, gdzie pierwsze kolumny w sa w postaci daty:

kolumna z 1 pliku:
11:26:11
11:26:12
11:26:13
......

kolumna z 2 pliku:

11:26:09.126
11:26:10.126
11:26:11.126
11:26:12.126
....

Chcialbym porownac poszczegolne wiersze i jesli sie zgadzaja daty, to kleje kolumny tych plikow:
 
my @tab;
 for (my $i=1; $i<=$#date; ++$i){
   for (my $j=1; $j<=$#date2; ++$j){
     if ($date[$i]->[0] ==grep(/^$_/,$date2[$j]->[1])){
     my @temp = (@{$date[$i]},@{$date2[$j]});
     open (PLIK,'>>plik.txt');
     print PLIK join ',' , @temp, "\\n";
     close PLIK;
NIestety wyskakuje blad: Use of uninitialized value in numeric eq (==) at ./fizyka.pl line 47.

Zatsanawiam sie czy moge dac warunek:
if ($date[$i]->[0] ==grep(/^$_/,$date2[$j]->[1])