Zapisywanie zmiennych dynamicznych

0

Ktoś może mi dać namiary? - jakiś artukuł, przykład szczególnie jeżeli chodzi o tablice dynamiczne

0

dla pliku amorficznego

BlockWrite(plik,tablica,sizeof(tablica));

albo w pętli dla pliku typowanego

for i := 0 to length(tablica)-1 do write(f,tablica[i]);

analogicznie z odczytem.

do czegoś tak prostego ma być artykuł?

0

Wszystko co się wie jest proste...dzięki, zapomniałem o plikach niezdefiniowanych :)

0

dla pliku amorficznego

BlockWrite(plik,tablica,sizeof(tablica));

eee ? dla tablicy dynamicznej to będzie raczej:

BlockWrite(plik,tablica[0],length(tablica));
0

eee ? dla tablicy dynamicznej to będzie raczej:

BlockWrite(plik,tablica[0],length(tablica));

szczególnie, jak zapisujesz do pliku nietypowanego. wtedy zapiszesz tyle bajtów, ile elementów ma tablica, a to przeważnie za mało ;-)
poza tym adres tablica i tablica[0] jest taki sam, bo tablica zaczyna się od zerowego elementu...

0

Szanowny ŁK to nie działa...(bez komentarzy)
Dajcie trochę wzkazówek albo jakieś namiary. To jest rzeczywiście takie proste, że szkoda gadać (opinia ŁK)?
Jak Piechnat poradził - działa tylko nie wiem co z Rewrite i Reset jak dam Rewrite(plik) to nie działa, jak dam Rewrite(plik,1), to zapisze i odczyta tylko pokaże Runtime error 204, jak dam Rewrite(plik, SizeOf(tablica)) to sie wiesza.
W moim programie sprawa nie będzie chyba prosta. Mam trochę skompikowane struktury - recordy składające się m. in. z dynamicznych tablic recordów itd. To mi wszystko działa tylko muszę to zapisywać (kurde może trzeba bylo od tego zacząć?). Jak to zapisywać?

// ŁF!!!!!!

0

No cóż, pomyłki chodzą po ludziach, a mi w D5 to też nie bardzo działa. Działa natomiast takie coś :

type
    TRekord = record
        zm1 : byte;
        zm2 : string[20];
    end;
var
    tablica : array of TRekord;
    F : file of TRekord;
begin
    SetLength(tablica, 3);
    AssignFile(F, 'd:\\plik.rec');
    Rewrite(F);
    BlockWrite(F, tablica[0], Length(tablica));
    CloseFile(F);
end;

//DOPISANE
i ŁF a nie ŁK


lub var f:file; //... rewrite(f,1); BlockWrite(F, pointer(tablica)^, Length(tablica)*sizeof(trecord)); pointer(tablica)^ da ten sam efekt co tablica[0], a </u>Length(tablica)*sizeof(trecord)</u> jest chyba oczywiste ;] [mf]
0

Tą sytuację rozumiem, tylko co zrobić kiedy jedno z pól rekordu jest tablicą dynamiczną?

0

Tą sytuację rozumiem, tylko co zrobić kiedy jedno z pól rekordu jest tablicą dynamiczną?

To masz problem, mozesz to zapisac do nietypowanego, ale potem tego nie odczytasz, musialbys wymysles jakis wlasny format, najpierw jakis naglowek, w nim zapisane informacje o wielkosci danych, po jego odczytaniu wiesz jaka dlugosc ma tablica i ja czytasz.

0

Dzięki :) ..."ja wiedziałem że tak będzie"...
Ale jak ktoś robił coś takiego, to niech wrzuci przykład, jak ja to zrobię, to dam znać

0

Wystarczy troche poglowkowac:

Prosty przyklad z zapisywaniem kilku tablic dynamicznych w jednym pliku, nie wiem czy nie ma bledow, bo mam kopniete delphi i nic nie chce sie instalowac, ale glownie chodzi o idee:

zapisywanie

procedure TForm1.Button1Click(Sender: TObject);
type
  MyString = String[50];
  THeader = record
    Name: String[10];
    Length: Integer;
  end;
var
  tablica : array of MyString;
  Header: THeader;
  F : file;
begin
  AssignFile(F, 'd:\\plik.rec');
  Rewrite(F); //standard

  //Robimy se 1 tablice
  SetLength(tablica, 3);
  tablica[0] := 'jakis ciag w 1 tablicy';
  tablica[1] := 'ciag 2 w 1 tablicy';
  tablica[2] := 'ciag 3 w 1 tablicy';

  //zapisujemy
  Header.Name := 'tablica 1';
  Header.Length := Length(tablica);
  BlockWrite(F, Header, SizeOf(Header));
  BlockWrite(F, tablica[0], Length(tablica) * SizeOf(MyString));

  //Robimy se 2 tablice
  SetLength(tablica, 2);
  tablica[0] := 'jakis ciag w 2 tablicy';
  tablica[1] := 'ciag 2 w 2 tablicy';

  //zapisujemy
  Header.Name := 'tablica 2';
  Header.Length := Length(tablica);
  BlockWrite(F, Header, SizeOf(Header));
  BlockWrite(F, tablica[0], Length(tablica) * SizeOf(MyString));

  CloseFile(F);
end;

odczytywanie

procedure TForm1.Button2Click(Sender: TObject);
type
  MyString = String[50];
  THeader = record
    Name: String[10];
    Length: Integer;
  end;
var
  tablica : array of MyString;
  Header: THeader;
  F : file;
  q: Integer;
begin
  AssignFile(F, 'd:\\plik.rec');
  Reset(F); //standard

  BlockRead(F, Header, SizeOf(Header));
  SetLength(tablica, Header.Length);
  BlockRead(F, tablica[0], Length(tablica) * SizeOf(MyString));
  Memo1.Lines.Add(Header.Name);
  for q := Low(tablica) to High(tablica) do
    Memo1.Lines.Add(tablica[q]);

  CloseFile(F);
end;

// posadziłeś byki - musi być reset(f,1) i rewrite(f,1) - bo to są pliki amorficzne - ŁF
// o tym nie wiedzialem, thx.

0

Dzięki za cierpliwość. To pojąłem. Sprawa z zapisem tablic dynamicznych jest jasna. Header zawiera informacje o tablicach. Tylko mi chodzi o sprawę zasadniczą (która być może nie stanowi problemu tylko nie wiem jak się do tego zabrać)
Czy można zapisać w całości np. coś takiego?
Trec=record
field1:Integer;
field2:array of string[50];
end;

0

to JEST proste, tak jak pisałem wcześniej z małymi poprawkami (bo sizeof(a)=4, a a^ nie działa)

var
  f : file;
  a : array of ShortString;
  i : integer;
begin
// tu zapisywanie
SetLength(a,10000);
for i := 0 to 9999 do
  a[i] := inttostr(i);
assign(f,'plik');
rewrite(f,1);
blockwrite(f,a[0],sizeof(a[0])*length(a));
close(f);

// tu odczyt
setlength(a,1); // 1 potrzebne do pobrania rozmiaru elementu tablicy
assign(f,'plik');
reset(f,1);
setlength(a,filesize(f) div sizeof(a[0]));
blockread(f,a[0],sizeof(a[0])*length(a));

close(f);
end.

[dopisane]
cholera, nie zauważyłem że temat ma dwie strony....

Czy można zapisać w całości np. coś takiego?
Trec=record
field1:Integer;
field2:array of string[50];
end;

nie możesz, bo tablica dynamiczna jest tak naprawdę tylko wskaźnikiem. sizeof(trec)=8 - 4 bajty integer i 4 tablica dynamiczna. ale nie zawsze musisz zapisywać długość (patrz kod wyżej), a jak się zaprzesz, to możesz zapisywać sobie stringi do pliku tekstowego wraz z ich ilością.

0

Ok, wielkie dzięki nauczyliście mnie zapisywać tablice dynamiczne ale powiedzcie czy da się zapisać w całości coś takiego:

Trec=record
field1:Integer;
field2:array of string[50];
end;

0

Ok, wielkie dzięki nauczyliście mnie zapisywać tablice dynamiczne ale powiedzcie czy da się zapisać w całości coś takiego:

Trec=record
field1:Integer;
field2:array of string[50];
end;

Tak samo jak wczesniej, czyli odczytujesz headera, powiekszasz tablice w rekordzie i wczytujesz jego zawartosc z pliku.

0

Ok, tylko jak to zapisać? (tylko nie mów że odwrotnie jak odczytać)

0

Glowy nie dam, bo pisze ze stronki, ale bedzie to cos takiego, czyli podobne do poprzedniego. nie wiadomo jak z ta tablica (czy zadziala sizeof calego rekordu), jak nie to bedzie cie to kosztowac troche matematyki z wyliczeniem wielkosci rekordu (przy zapisaniu) i dlugosci tablicy (przy odczytywaniu)

procedure TForm1.Button1Click(Sender: TObject);
type
 THeader = record
  Length: Integer;
 end;
 TRecord = record;
   cos: Integer;
   tablica: array of String[20];
 end;
var
 rec: TRecord;
 Header: THeader;
 F : file;
begin
 AssignFile(F, 'd:\\plik.rec');
 Rewrite(F, 1);

 //Tu se cos z tym rekordem robisz

 //zapisujemy
 Header.Length := Length(Rec.tablica);
 BlockWrite(F, Header, SizeOf(Header));
 BlockWrite(F, Rec, SizeOf(Rec));

 CloseFile(F);
end;

procedure TForm1.Button2Click(Sender: TObject);
type
 //jak wyzej
var
 //jak wyzej +
 q: Integer;
begin
 AssignFile(F, 'd:\\plik.rec');
 Reset(F, 1);


 BlockRead(F, Header, SizeOf(Header));
 SetLength(Rec.tablica, Header.Length);
 BlockRead(F, Rec, SizeOf(Rec));

 //odczytany rec

 CloseFile(F);
end; 

<font color="darkblue">//rozmiar mozna bardzo latwo policzyc dodajac do siebie wszystko co jest w rekordzie + dlugosc tablicy * wielkosc jej elementu, troszke trudniej z wyliczeniem dlugosci na podstawie wielkosci ale jak napisalem troszke</span>

0

Chyba problem sprowadza się tylko do zapisu. I chyba to co zapisałeś nie zadziała
Z pewnością nie SizeOf(rec) ponieważ ta funkcja nie da rozmiaru zmiennej tworzonej dynamicznie. Size rec można łatwo obliczyć:=mem2-mem1 gdzie m1:=AllocMemSize przed wypełnieniem recordu a m2 po jego wypełnieniu. Ale i tak nic z tego... [???]
Dzisiaj już tego nie sprawdzę muszę wstać od kompa

0

nie kumam - dałem Ci działające rozwiązanie, co za problem dorzucić tam jeszcze odczyt jakiegoś integera?

0

A co ja mam powiedzieć? Wcześniej mówisz, że się nie da tego zapisać, teraz że no problem, chyba że jest was kilku ŁK, ale wielkie dzięki myślę, że nie był to czas stracony :)

// mówiłem, że nie da się tego zapisać w takiej postaci - nie przeczytałeś uważnie - ŁF

0

Oj przepraszam ŁF

// zabiję, wypatroszę, ugotuję, dam psom na pożarcie i zbanuję. no i jaja urwę. ŁF

0

Wróciłem do tego wątku bo skończyłem testowanie plików nietypowanych w swoim programie. Wolverine i ŁF - wielkie dzięki!!!
Dla tych co jeszcze nie stosowali plików niezdefiniowanych - to jest rewelacja. Jedna uwaga. Robiąc header(informacja o zapisywanych zmiennych) zapisujcie FilePos, żeby później nie było problemów z odczytem (Seek)

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