String, ograniczona ilość znaków

0

W moim programie jest zapis rekordów przez pliki typowane na podstawie artykułu Adama Boducha. Była tam wzmianka że moze wystąpić błąd: [Error] MainFrm.pas(40): Type 'XXX' needs finalization - not allowed in file type Oczywiście taki mi wyskoczył, Adam zalecił określenie długości stringów poprzez String[200] Pomogło ale mi są potrzebne stringi z dlugoscią max 2000, jak to wpisze to pojawia sie błąd że max moze byc 255, czy delphiemu sie przypadkiem stringi nie pomyliły z shortstring?

Inne pytanie, jak utworzyc plik jezeli go nie ma (dalej pliki typowane) Rewrite u mnie nie działa

0

AnsiString (string + F1), a co do zapisywania plików, pokaż fragment kodu za to odpowiedzialny.</delphi>

0

Jak daje AnsiString to dalej ten sam blad. Z zapisywaniem juz sobie poradzilem. Jak usunąć jakiś rekord z pliku typowanego? Na przykladzie dodawania do pliku:

procedure TForm1.ButtonDodajClick(Sender: TObject);
var
StrucRec : TZbior;
begin
ListBox1.Items.Add(LabeledEditTemat.Text);

 AssignFile(DaneBase, FileName);
  if not FileExists(FileName) then // Jezeli plik nie istnieje - nie rob nic
    ReWrite(DaneBase) else
  Reset(DaneBase);
  Seek(DaneBase, FileSize(DaneBase)); // przesunięcie na koniec pliku

  StrucRec.Temat := LabeledEditTemat.Text;
  StrucRec.Notka := Memo1.Text;

   write(DaneBase, StrucRec); // zapisanie rekordu do pliku

   CloseFile(DaneBase);  // zamknięcie pliku
   ListBox1.Clear; // wyczyszczenie komponentu
   FormCreate(Sender); // wywołanie procedury OnCreate

end;
0

nie ma stringów o statycznej długości większej niż 255. pozostaje Ci albo dynamiczny string (ale wtedy będziesz mieć kłopoty przy zapisie do plików), albo pchar/array[0..2000] of char.

TZbior - co to jest?

rewrite - to musi działać, jeśli nie, to błąd leży w użyciu tej procedury (np.: złe parametry).

0

Rewrite juz dziala

A tu wyjasnienie TZbior:

type
  TZbior = packed record
    Temat: string[200];
    Notka: char;
    end;

    TDaneFile = file of TZbior; // wskazanie na rekord [ nowy typ ]

var
  Form1: TForm1;
  DaneBase: TDaneFile;

Ile znaków mogą mieć Char i Pchar? Zawsze uzywalem stringów

EDIT: Chyba nie bede sie z tym brandzlował i spróbuje zapisac rekordy do pliku textowego za pomocą zwykłej operacji na plikach. Powiedzcie mi tylko czy w operacji na plikach działa Seek (ustawienie pozycji w pliku) może jest jakas inna funkcja która pozwala odwoływać sie do kolejnych lini w pliku tekstowym?

0

w plikach tekstowych nie ma funkcji Seek, szczerze mowiac zamiast bawic sie w pliki tekstowe to juz lepiej pokombinuj z p. typowanymi.
Jezeli chcesz miec dostep do okreslonej linni w pliku tekstowym to najlepiej uzyc strumieni czyli np. TStringList i potem juz powinno isc latwo.

0

W sumie mozna by to tak załatwić, ale w ten sposób chyba bede musial zaladowac wszystkie rekordy do pamieci, a jak juz wspomnialem moze ich byc 2000. Z wykorzystaniem plików typowanych wczytywany zostaje aktualnie potrzebny rekord prosto z pliku wiec wydaje mi sie że zajmuje mniej w pamieci. W tej chwili mam problem tylko z <ort>usówaniem </ort>rekordu i tymi wielkościami stringów :-/

0

Piszę z pamięci więc mogą być małe błędy:

Rekord:

type TZbior = packed record
Temat: AnsiString;
Notka: AnsiString;
end;

Zapis:

var Rek: array of TZbior;
    i: Integer;
    Stream: TStream;
    Len: Cardinal;
begin
  Stream:=TFileStream.Create('nazwa_pliku', fmCreate);
  try
    Len:=Length(Rek);
    Stream.WriteBuffer(Len, SizeOf(Len));
    for i:=0 to High(Rek) do
    begin
      Len := Length(Rek[i].Temat);
      Stream.WriteBuffer(Len, SizeOf(Len));
      Stream.WriteBuffer(Pointer(Rek[i].Temat)^, Len);
      Len := Length(Rek[i].Notka);
      Stream.WriteBuffer(Len, SizeOf(Len));
      Stream.WriteBuffer(Pointer(Rek[i].Notka)^, Len);
    end;
  finally
    Stream.Free;
  end;
end;

Odczyt:

var Stream: TStream;
    Rek: array of TZbior;
    Len: Cardinal;
    i: integer;
begin
  Stream:=TFileStream.Create('nazwa_pliku', fmOpenRead);
  try
    Stream.ReadBuffer(Len, SizeOf(Len));
    SetLength(Rek, Len);
    for I:=0 to High(Rek) do
    begin
      Stream.ReadBuffer(Len, SizeOf(Len));
      SetLength(Rek[i].Temat, Len);
      Stream.ReadBuffer(PChar(Rek[i].Temat)^, Len);
      Stream.ReadBuffer(Len, SizeOf(Len));
      SetLength(Rek[i].Notka, Len);
      Stream.ReadBuffer(PChar(Rek[i].Notka)^, Len);
    end;
  finally
    Stream.Free;
  end;
end;
0

Jakie moge użyć rozszerzenie ?

0
Dibo84 napisał(a)

Jakie moge użyć rozszerzenie ?

:|

0

Ok, poczytałem chwile o strumieniach, nie chce tylko tego skopiować ale także zrozumieć. Przy pierwszym uruchomieniu programu jest ok, zapisyje itp. Jednak przy kolejnym wywala mi takie coś:

Access violation t addres 7D38C2C n module 'user32.dll' Read of address 0000004
, po wcisnieciu OK pojawia sie kolejne okno z błędem, takim samym tylko z innymi liczbami
A to procedura odczytu, pewnie coś namieszałem:

procedure TForm1.ReadDate;
var
  fsKart : TFileStream;
  I : Integer;
begin
  if not FileExists(FileName) then Exit; // Nie rob nic jezeli plik nie istnieje

  fsKart := TFileStream.Create(FileName, fmOpenReadWrite); // odczytaj plik
  SetLength(Dane, fsKart.Size div SizeOf(TZbior)); // ile jest danych??

  For I := Low(Dane) to High(Dane) do
  begin
    fsKart.Read(Dane[i], SizeOf(TZbior));
    ListBox1.Items.Add(Dane[i].Temat);
  end;
  fsKart.Free;
end;

EDIT: Kurcze zmeczony chyba jestem, blad naprawilem, zostaly mi resztki kodu po plikach typowanych dlatego cos sie kaszaniło. Za to teraz dziwnie mi zapisuje, tzn. jak edytuje plik "dane.dat" to są tam same kwadracki, a przy uruchomieniu programu zamiast moich rekordów w labeleditach są same ślaczki. Podaje więc jeszcze kod zapisu:

procedure TForm1.WriteDate;
var
  fsKart : TFileStream;
  I : Integer;
begin
 fsKart := TFileStream.Create(FileName, fmCreate); // Utworz strumien
 For I := Low(Dane) to High(Dane) do
  begin
    fsKart.Write(Dane[i],  SizeOf(Dane[i]));  // zapisz do pliku
  end;
  fsKart.Free; // zwolnij zmienna
end;

EDIT2: Bład naprawiony, nie zauwazylem że znowu mialem same stringi bez ograniczenia w [xxx], czyli powróciłem do początku [rotfl] ;( . Za ciezki dla mnie ten delphi, chyba wracam do grafiki...

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