Plik rekordowy w Lazarusie

0

Witam.
Muszę przerobić gotowy program napisany w Pascalu z trybu tekstowego na graficzny. W tym celu używam Lazarusa, jednak napotkałem dość dziwny problem. Nie mogę utworzyć pliku rekordowego.

nazwa_rekordu = record
cos:byte;
cos2:string;
end;

baza = file of pytanie;
 

Otrzymuję następujący błąd: "Error: Typed files cannot contain reference-counted types." w linii, w której tworzę typ plikowy o nazwie baza. O co mu chodzi?

0

Otrzymuję następujący błąd: "Error: Typed files cannot contain reference-counted types." w linii, w której tworzę typ plikowy o nazwie baza. O co mu chodzi?

Jaką masz wersję FPC i Lazarusa. U mnie jest w porządku (nie wiem czy mam najnowszy FPC).

1

nie możesz zapisywać w pliku typowanym czegoś co nie ma podanego rozmiaru (np. string)

0

nie możesz zapisywać w pliku typowanym czegoś co nie ma podanego rozmiaru (np. string)

Boże zapomniałem o tym... Misiekd ma racje, musisz użyć shortstring.

0

Dzięki za pomoc, działa również zapis cos:string[255].
Mam jednak kolejny problem, tym razem z funkcją FileSize. Zwraca zawsze jakieś chore wartości, najpierw w ogóle się nie kompilowała (wersja Filesize(nazwa_zmiennej_plikowej)), jednak doczytałem, że w parametrze należy wstawić ścieżkę do pliku, mimo wszystko nadal świruje. Istnieje jakaś inna możliwość odczytania ilości rekordów w takim pliku?

0

FileSize(ZmiennaPlikowa) poda Tobie rozmiar pliku w bajtach tylko dla File of Byte. Dla typów rekordówych jak u Ciebie poda Tobie ilośc rekordów w pliku.

0

No właśnie chcę uzyskać liczbę rekordów, a dostaję jakieś głupoty, np. -1.

0

TFileStream Size + Help/google

0

To może ja pokażę dokładniej co jest nie tak.

procedure TForm4.Button1Click(Sender: TObject);
begin
  val(s1,rec.cos);
  rec.cos2:=s2;
  x:=GetFileSize('sciezka_do_pliku');
  reset(baza);
  seek(baza,x);
  write(baza,pyt);
  CloseFile(baza);
  Form4.Hide;
  Form2.Show;
end;              

Tutaj przy użyciu funkcji:

function GetFileSize(const FileName: string):Int64;
 var
    ms : tmemorystream;
 begin
    if not FileExists(FileName) then
       Result:=0
    else
    begin
      ms := tmemorystream.Create;
      ms.LoadFromFile(filename);
      result:=ms.Size;
      Freeandnil(ms);
    end;
 end;    

W takim wypadku, program nie dodaje wprowadzonego rekordu do pliku, tylko zostawia go jakby otwartego. Podczas wyświetlania wszystkie dalsze rekordy (do nieskończoności) wypełnione są pustymi wartościami. TFileStream nie bardzo ogarniam, ale zakładam że też pewnie nie będzie chciał współpracować. Co jest nie tak?

0

Brawo za same zmienne globalne!

procedure TForm4.Button1Click(Sender: TObject);
begin
  val(s1,rec.cos);
  rec.cos2:=s2;
  assignFile(baza,'plik');
  reset(baza);
  seek(baza,filesize(baza));
  write(baza,pyt);
  CloseFile(baza);
  Form4.Hide;
  Form2.Show;
end;

Takie trudne? Tak wiem.

0

czytałeś to co napisałem wcześniej??? Masz tam gdzieś TMemoryStream?? Wiesz co robisz w tej twojej magicznej funkcji?? BTW pewnie o Append nie słyszałeś

0

Tak, trudne. Przynajmniej czytanie ze zrozumieniem...
Jak już wyżej napisałem funkcja filesize zwraca głupoty i powoduje dokładnie to samo co wyżej wklejona przeze mnie funkcja GetFileSize.

Znalazłem jeszcze taką:

function GetFileSize(const FileName: string):Int64;
var
   FS:TFileStream;
begin
   if not FileExists(FileName) then
      Result:=0
   else
   begin
      FS.Create(FileName,fmOpenRead or fmShareCompat);
      Result:=FS.Size;
      FS.Free;
   end;
end; 

Tym razem z użyciem TFileStream. Jednak po wykonaniu wyskakuje błąd: "Project raised exception class 'External: SIGSEGV'.".

0

ale Ty nie masz podstawowej wiedzy o klasach i obiektach. FS := TFileStream.Create(FileName,fmOpenRead or fmShareCompat);

0

O Append słyszałem.
Także o tym, że jest wykorzystywany w plikach tekstowych... ja takiego nie mam.

Gdybym miał pojęcie to czy pytałbym o takie funkcje w dziale Newbie? Oczekiwałem raczej pomocy niż ciągłego opieprzania...
BTW. Nie jestem autorem tych funkcji, skopiowałem je z: Odczyt rozmiaru pliku

Po zmianie program zaczyna świrować jak przy użyciu zwykłego filesize, bądź pierwszej wersji funkcji GetFileSize.

0

to może daj wreszcie CAŁY kod a nie jakieś marne kawałki

0

To jest praktycznie cały kod. Nie sądziłem że assign i deklaracja zmiennej plikowej i typu rekordowego jest taka ważna. Problem jest tylko z odczytaniem rozmiaru pliku, cała reszta chodzi bez problemu. Jeżeli ręcznie ustawię wartość x na rozmiar tego pliku to też wszystko działa. Jedynie ten filesize z niewyjaśnionych przyczyn robi mi takie dziwne problemy.

Może trochę niedokładnie wcześniej wyjaśniłem. Wszystkie wcześniej wymienione funkcje zwracają po prostu dziwną liczbę. W przypadku mojego pliku wypełnionego czterema rekordami jest to 20. W takim wypadku wszystkie pola 5-19 są tworzone jako puste, a na 20 wprowadzane są wartości podane przez użytkownika. Jednak dziwne jest też, że po takim dodaniu można wyświetlić dowolny nr rekordu (np. 255) i będzie on miał puste pola. Wcześniej, próba wyświetlenia czegoś co nie znajduje się w pliku kończyła się błędem.

0

Może trochę niedokładnie wcześniej wyjaśniłem. Wszystkie wcześniej wymienione funkcje zwracają po prostu dziwną liczbę. W przypadku mojego pliku wypełnionego czterema rekordami jest to 20. W takim wypadku wszystkie pola 5-19 są tworzone jako puste, a na 20 wprowadzane są wartości podane przez użytkownika. Jednak dziwne jest też, że po takim dodaniu można wyświetlić dowolny nr rekordu (np. 255) i będzie on miał puste pola. Wcześniej, próba wyświetlenia czegoś co nie znajduje się w pliku kończyła się błędem.

Mój kod działa, ty po prostu nie rozumiesz że twoja funkcja zwróci rozmiar w BAJTACH a mój kod działa na ilościach rekordów (tak jak to się powinno robić).

Jeżeli dalej masz problem to pokaż cały kod.

0
type
rekord = record
cos:string;
cos2:byte;
end;

bazadanych = file of rekord;

var
baza:bazadanych;

{ktoras z wczesniejszych funkcji GetFileSize}

procedure dodaj(var baza:bazadanych);
var
x:byte;
rec:rekord;
begin
  rec.cos:='costam';
  rec.cos2:=2;
  x:=GetFileSize('sciezka_do_pliku');
  reset(baza);
  seek(baza,x);
  write(baza,rec);
  CloseFile(baza);
end;  

begin
assign(baza, 'nazwa.dat');
dodaj(baza); 
end.  
1

napisałem Ci w pierwszym moim poście - cos2 NIE MOŻE BYĆ TYPU STRING

0

Jeszcze od siebie dodam że mi też ostatnio FileSize nie chciał działać, żądał ansistringa jako parametr. Jeżeli ktoś ma z tym problem to niech to przerobi na system.FileSize(blabla);.

0

No i wielkie dzięki -123!
system.FileSize działa dokładnie tak jak trzeba. Fajnie że ktoś jeszcze potrafi konkretnie pomóc, zamiast czepiać się innych drobnych szczegółów.

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