[pascal] wczytywanie bazy danych z .txt

thim
Użytkownik
Użytkownik
Posty: 4
Rejestracja: 15 lut 2010, o 13:51
Płeć: Mężczyzna
Podziękował: 1 raz

[pascal] wczytywanie bazy danych z .txt

Post autor: thim »

Pisze program na infe, który ma wczytać dane z pliku .txt do bazy danych (lista dwukierunkowa).
Z pliku BookList.txt o wyglądzie

Kod: Zaznacz cały

tytuł1,imie1,nazwisko1
tytuł2,imie2,nazwisko2
tytuł3,imie3,nazwisko3
...
ma wczytać informacje do bazy

Kod: Zaznacz cały

Book = record
         Title:         string;
         Name:          string;
         ScName:        string;
End;
odpowiednie słowa.
Problem polega na tym, że nie działa procedura mająca rozdzielić poszczególne słowa z wiersza.Wygląda ona mniej więcej tak:

Kod: Zaznacz cały

procedure ReadBk;
var
   zn: char;
   znaki: string;
   t: tab2;    {tablica do której wprowadzam podzielone słowa}
   n: integer;

begin
     {reset(Bklist);}
     writeln('Wczytywanie listy ksiazek.');
     repeat
     n:=1;
           repeat
           read(bklist,zn);
           if zn<>',' then znaki:=znaki+zn
           else
               begin
               t[n]:=znaki;
               znaki:='';
               n:=n+1;
               end;

           until eoln(bklist);
     for i:=1 to 3 do
         write(t[i], ',');   {to jest pętla kontrolna: wlasnie tu widac ze cos nie dziala}
     writeln;
     {tu przekazuje tablice t do procedury ładującej ją do recordu}
     read(bklist);
     until eof(bklist);
     writeln('Wczytano liste ksiazek!');
end;  {ReadBk............................}
Dokładnie wygląda to tak, że gdy drukuje na ekran zwartość tablicy przy każdej linijce wygląda to mniej wiecej tak

Kod: Zaznacz cały

nazwisko3,tytuł1,imie1
nazwisko1,tytuł2,imie2
nazwisko2,tytuł3,imie3
i nie bardzo wiem czemu zaczyna drukowac od ostaniego słowa.
Czy mogę liczyc na pomoc w jakiej kolwiek postaci (podpowiedz, wskazanie błędu, gotowy kod)
Thx in advance :d
smiechowiec
Użytkownik
Użytkownik
Posty: 374
Rejestracja: 21 cze 2007, o 11:28
Płeć: Mężczyzna
Lokalizacja: Łostowice
Pomógł: 146 razy

[pascal] wczytywanie bazy danych z .txt

Post autor: smiechowiec »

Nie zamieściłeś całego kodu więc nie jestem pewien co do Twojego rozwiązania.
Ewentualny błąd kryje się w pętli wczytującej,
dodajesz elementy tylko wtedy gdy napotkasz znak przecinka
w związku z tym po dojściu do końca linii nie zaczytujesz ostatniego słowa,
nie zerujesz też prawdopodobnie bufora znaki,
dodajesz do zmiennej znaki znaki końca linii (#10, #13)

Może warto wczytać kolejne linie z całym rekordem i odpowiednio przypisać do pól.

Kod: Zaznacz cały

var
   Bklist : Text;

{ Zwraca liczbę pozycji w LINIA oddzielonych separatorem SEP }
function fnumentries(linia : string; sep : string) : Integer;
var i : Integer;
begin
  i := 1;
  while (pos(sep, linia) > 0) do begin
    linia := copy(linia, pos(sep, linia) + 1, length(linia));
    inc(i);
  end;
  fnumentries := i;
end;

{ zwraca pozycję NR z listy LINIA, oddzielonej separatorem SEP }
function fentry(nr : Integer; linia : string; sep : string) : String;
var
  i, j : Integer;
 begin
  i := 1;
  j := fnumentries(linia, sep);
  while (pos(sep, linia) > 0) and (i < nr) and (i <= j) do begin
    linia := copy(linia, pos(sep, linia) + 1, length(linia));
    inc(i);
  end;
  if (i = nr) then Begin
    if (pos(sep, linia) > 0) then
      linia := copy(linia, 1, pos(sep, linia) - 1)
  End
  else if ((nr > j) or (nr < 1)) then
    linia := '';

  fentry := linia;
end;


procedure ReadBk;
var
   linia: string;
   i, n : Integer;
begin
     writeln('Wczytywanie listy ksiazek.');
     n := 0;
     repeat
       readln(bklist, linia);
       for i := 1 to 4 do
         write(fentry(i, linia, ','), '  ');
       writeln;
       Inc(n);
     until eof(bklist);
     writeln('Wczytano ', n, ' ksiazek!');
end;

begin
  writeln('Program ...');
  Assign(Bklist, 'BookList.txt');
  reset(Bklist);
  ReadBk;
  Close(Bklist);
end.
thim
Użytkownik
Użytkownik
Posty: 4
Rejestracja: 15 lut 2010, o 13:51
Płeć: Mężczyzna
Podziękował: 1 raz

[pascal] wczytywanie bazy danych z .txt

Post autor: thim »

Dzięki bardzo!
Szalenie profesjonalny ten kod (mysle, że jesli nadal bede slęczał nad Pascalem przyda mi sie nie raz )
Mam tylko jedno pytanie: co zwracają funkcje pos() i copy()
smiechowiec
Użytkownik
Użytkownik
Posty: 374
Rejestracja: 21 cze 2007, o 11:28
Płeć: Mężczyzna
Lokalizacja: Łostowice
Pomógł: 146 razy

[pascal] wczytywanie bazy danych z .txt

Post autor: smiechowiec »

To standardowe funkcje dostępne w pascalu, opis z internetu

Copy(s, m, n) - zwraca podłańcuch o długości m znaków wycięty z łańcucha s poczynając od pozycji n;

Pos(ch, s)- zwraca numer pozycji, na której w łańcuchu s znajduje się znak ch;

thim
Użytkownik
Użytkownik
Posty: 4
Rejestracja: 15 lut 2010, o 13:51
Płeć: Mężczyzna
Podziękował: 1 raz

[pascal] wczytywanie bazy danych z .txt

Post autor: thim »

Dobra, dzięki
Niestety sprawdzę jak ten kod funkcjonuje w programie dopiero jutro (niestety szkoła to jeszcze parę innych nieprzyjemnych rzeczy :P)
Wtedy wiec moze ostatecznie podziekuje (:D) lub będę dalej pytał
Pozdrawiam.

-- 19 lut 2010, o 18:55 --

Tak wiec oświadczam ze kod działa wyśmienicie :D
Zmieniłem tylko z

Kod: Zaznacz cały

for i := 1 to 4 do
    write(fentry(i, linia, ','), '  ');
writeln;
w ReadBk( ) na

Kod: Zaznacz cały

for i := 1 to fnumentries(linia,',') do begin             {!}
     t[i]:='';
     t[i]:=fentry(i, linia, ',');
end;
Zamiast wprowadzanej wewnętrzne liczby pozycji w wierszu petlę for ogranicza funkcja zwracająca tą liczbą (przy każdym wierszu moze byc ona (teoretycznie) inna, wiec tak na pewno wypisze wszystko).
Poza tym zamiast wypisywac na ekran, po prostu ładuję dane do tablicy, którą późnije przekażę procedurze tworzącej nowy record w liscie :D

Tak wiec wielkie dzięki!!!

//Próbowalem napisac posta 2 dni temu ale wyskakiwał jakiś błąd
ODPOWIEDZ