Nie chce działać instrukcja Reset lub rewrite

0

Witam.
Byłem w wątku Newbee ale nie wiem dlaczego został zlikwidowany.
Do rzeczy. Napisałem kilka programów. jedne generują dane a inne je wykorzystują i dalej przetwarzają. Ktoś zapyta czy nie można stworzyć jednego programu który będzie zawierał wszystko i bez problemu z komunikacją. Taki program będzie zawierał tysiące linii co jest niełatwe przy wyszukiwaniu błędów. poza tym oznaczenia zmiennych. Można używać długich nazw ale to jeszcze bardziej wydłuży program i koło zamyka się.
Próbowałem stosować instrukcje RESET i REWRITE w różnych konfiguracjach i nic. Gdzie popełniam błąd. Załączam program który generuje dane i je zapisuje a potem w celu sprawdzenia znów wyświetla. (Procedury DyskWrit i DyskRead)
Po uruchomieniu program żąda nazwy pliku do zapisu a po zatwierdzenia kończy działalność bez wyświetlenia błędu.

1

W jakim środowisku to piszesz? Delphi, Lazarus czy jeszcze coś innego?

Tak na szybko wrzuciłem to do Lazarusa. Całość się skompilowała bez jakichkolwiek problemów, ale program robi NIC. Po odpaleniu z poziomu IDE, pojawia się na jakąś sekundę okno z konsolą, które zaraz potem znika. Po odpaleniu ręcznie stworzonego exe'ka dostaję wynik jak na poniższym obrazku (nie ma nawet pytania o ścieżkę pliku):

screenshot-20190104173348.png

0

Ponieważ obliczenia trwają bardzo krótko więc wrzuciłem linię 196(DyskWrit) i linię 207 (DyskRead) do komentarza i wtedy wyświetlone są dane które powinny być zapisane. na pliku.

Write('Podaj nazwe zbioru na dysku = '); Readln(Nazwa);
Nazwa:='C:\LAZARUS\PAPIEROS\Dane'+Nazwa; Assign(Plik,Nazwa);
Rewrite(Plik);

1

W procedurze zapisującej:

Procedure DyskWrit (N: Integer; A: Wek);
  Var
    Nazwa: String[36];
    Plik: File of Double;
  Begin
//      Readln;
    Write('Podaj nazwe zbioru na dysku = '); Readln(Nazwa);
    Nazwa:='C:\LAZARUS\PAPIEROS\Dane\'+Nazwa; Assign(Plik,Nazwa);
    Reset(Plik);
    A[0,0]:= N+0.0;
    Write(Plik,A[0,0],A[0,1],A[0,2]);
    For k:=1 To N Do
       For l:=0 To 2 Do
         Write(Plik,A[k,l]);
    Close(Plik)
  End; //Dyskwrit

używasz Reset(Plik), czyli otwierasz plik do odczytu.

w procedurze odczytującej:

Procedure DyskRead;
  Var
    k, l: Integer;
    N: Integer;
    Nazwa: String[30];
    Plik: File of Double;
  Begin
    Write('Podaj nazwe zbioru na dysku = '); Readln(Nazwa);
    Nazwa:='C:\LAZARUS\PAPIEROS\Dane\'+Nazwa; Assign(Plik,Nazwa);
    Rewrite(Plik);
    Read(Plik, A[0,0]);
    N:= Round(A[0,0]);
    For k:=1 To N Do
      For l:=0 To 2 Do
        Read(Plik,A[k,l]);
    Close(Plik); ClrScr;
//    Writeln(#10,'Liczba pomiarów N= ',N,#10,#13);
    For i:=0 To N Do Writeln('z= ',A[i,0],'  p=',A[i,1],'  t=',A[i,1]);

  End;

używasz Rewrite(Plik) czyli otwierasz plik do zapisu.

Reszty nie przeglądałem ale to chyba już załatwia twój problem.

0
robertz68 napisał(a):

W procedurze zapisującej:

Procedure DyskWrit (N: Integer; A: Wek);
  Var
    Nazwa: String[36];
    Plik: File of Double;
  Begin
//      Readln;
    Write('Podaj nazwe zbioru na dysku = '); Readln(Nazwa);
    Nazwa:='C:\LAZARUS\PAPIEROS\Dane\'+Nazwa; Assign(Plik,Nazwa);
    Reset(Plik);
    A[0,0]:= N+0.0;
    Write(Plik,A[0,0],A[0,1],A[0,2]);
    For k:=1 To N Do
       For l:=0 To 2 Do
         Write(Plik,A[k,l]);
    Close(Plik)
  End; //Dyskwrit

używasz Reset(Plik), czyli otwierasz plik do odczytu.

w procedurze odczytującej:

Procedure DyskRead;
  Var
    k, l: Integer;
    N: Integer;
    Nazwa: String[30];
    Plik: File of Double;
  Begin
    Write('Podaj nazwe zbioru na dysku = '); Readln(Nazwa);
    Nazwa:='C:\LAZARUS\PAPIEROS\Dane\'+Nazwa; Assign(Plik,Nazwa);
    Rewrite(Plik);
    Read(Plik, A[0,0]);
    N:= Round(A[0,0]);
    For k:=1 To N Do
      For l:=0 To 2 Do
        Read(Plik,A[k,l]);
    Close(Plik); ClrScr;
//    Writeln(#10,'Liczba pomiarów N= ',N,#10,#13);
    For i:=0 To N Do Writeln('z= ',A[i,0],'  p=',A[i,1],'  t=',A[i,1]);

  End;

używasz Rewrite(Plik) czyli otwierasz plik do zapisu.

Reszty nie przeglądałem ale to chyba już załatwia twój problem.

Nic to nie daje a program dalej robi NIC jak napisał cerato

1

Trzy sprawy:

**1) **tak, jak pisałem (oraz dałem screena), aplikacja na Win10 64-bit robi NIC. Nie wnikając dlaczego tak się dzieje, sprawdziłem przed chwilą na poczciwym Windowsie XP. Program się uruchamia i pyta o nazwę pliku.

2) po wpisaniu nazwy pliku wyskakuje błąd. Tutaj popieram to, co napisał wcześniej @robertz68 - jeśli masz procedurę o nazwie DyskWrit, która ma pisać do pliku, to nie możesz go otwierać przez reset, bo Reset - Open file for reading https://www.freepascal.org/docs-html/rtl/system/reset.html. Zmieniłem reset na rewrite ale ponownie wyskoczył (czego się zresztą spodziewałem) błąd.

3) zmieniłem podaną przez Ciebie ścieżkę/lokalizację pliku z "C:\LAZARUS\PAPIEROS\Dane\" na "C:\" i program zadziałał. Stworzył w katalogu głównym dysku C: jakieś pliki o podanej przeze mnie nazwie, miały one rozmiar większy od zera, więc zostały wypełnione jakimiś danymi.

Podsumowując - po poprawieniu błędów z pkt.2 aplikacja działa poprawnie. Możesz ewentualnie spróbować zapisać u siebie pliki wynikowe do katalogu głównego i sprawdzić, czy da to jakiś efekt.

Daj proszę znać, czy udało Ci się aplikację odpalić, czy nadal są problemy.

0
    Nazwa:='C:\LAZARUS\PAPIEROS\Dane\'+Nazwa; Assign(Plik,Nazwa);
    Rewrite(Plik);
    Read(Plik, A[0,0]);

The rewrite procedure opens a file given by FileHandle for writing.
You must use AssignFile to assign a file to the FileHandle before using Reset.
If the file does not exist, it is created.
If the file already exists, the contents are lost, and new data is added to the start.

http://www.delphibasics.co.uk/RTL.asp?Name=rewrite

(AssignFile to to samo co Assign)

0

Witam
Zastosowałem się do wskazówek ale pojawił się niezrozumiały błąd w procedurze DyskWrit (linia 35). Zastosowałem 2 sposoby podstawienia, jest dalej błąd. Otwiera się okno Asemblera i wykonuje się kilka instrukcji i zakończenie programu (przy krokowym wykonaniu programu)

Mam Win10

1

To może mieć jakiś związek z systemem. U mnie na XP działa OK, natomiast na Win10 64-bit (jak pisałem kilka postów wcześniej) robi totalne NIC, aczkolwiek może to wynikać równie dobrze z czegoś innego - np. antywirusa. Podeślę sobie tego samego EXE, który działał na XP i jutro przetestuję jego zachowanie w firmie.

A odnośnie błędu, o którym piszesz w ostatnim poście - fajnie, jakbyś napisał coś więcej, a nie jedynie "znowu jest błąd". Im więcej szczegółów, tym łatwiej coś wykombinować.

0

A odnośnie błędu, o którym piszesz w ostatnim poście - fajnie, jakbyś napisał coś więcej, a nie jedynie "znowu jest błąd". Im więcej szczegółów, tym łatwiej coś wykombinować.

Więcej szczegółów:
Win10 64bit

Fragment procedury DyskWrit:
Write('Podaj nazwe zbioru na dysku np. = C:\Silnik.10 '); Readln(Nazwa);
Nazwa:='C:'+Nazwa;
Assign(Plik,Nazwa);
Rewrite(Plik);
A[0,0]:= N1(+0.0);
W instrukcji A[0,0]:= N1(+0.0); pojawia się wspomniany wcześniej błąd
W komentarzu jest próba zamiany zmiennej N1 - Integer na Double aby dopasować A[0,0]:= N1+0.0; bez zmian - błąd

W programie głównym jest identyczne podstawienie i błędu nie ma
A[0,0]:= N1; A[0,1]:= 0.0; A[0,2]:= 0.0;

1

A do czego tam jest to + 0.0.? W Lazarusie nie można zapisać do zmiennej double wartości integer?
Odnośnie wcześniejszego problemu który chyba rozwiązał @cerrato to masz ustawiony na sztywno długości ścieżki do pliku a do tego jeszcze 2 różne długości. Raz Nazwa: String[36]; przy zapisie i Nazwa: String[30]; przy odczycie. Jeśli już chcesz ograniczać długość to dla konsoli maksymalna długość ścieżki to 260. I powinna ta wartość być taka sama dla zapisu i odczytu.

0
Clarc napisał(a):

A do czego tam jest to + 0.0.? W Lazarusie nie można zapisać do zmiennej double wartości integer?

W tej chwili jest to w komentarzu ale wcześniej miało służyć do zamiany zmiennej N1 - Integer na Double - A[0,0]
Obecnie jest to samo String[15]

0

Ale typ integer można bez problemu zapisać do double. W drugą stronę trzeba ucinać/konwertować wartość.
Napisałeś:

A[0,0]:= N1(+0.0);

W programie głównym jest identyczne podstawienie i błędu nie ma
A[0,0]:= N1;

Ja tam nie widzę żeby to było identyczne.

0

Nie bardzo rozumiem wcześniej napisałeś - cytat

A do czego tam jest to + 0.0.? W Lazarusie nie można zapisać do zmiennej double wartości integer?

0

Jeśli dobrze pamietam to w C++, Pythonie i może jeszcze gdzieś jest coś takiego, że dla zmiennej całkowitoliczbowej, żeby przejść na wartość zmiennoprzecinkową to robi się takie zabiegi jak:
'float' := 'integer' + 0.0; np. żeby uzyskać rzeczywistą wartość przy dzieleniu a nie tylko cześć całkowitą.

W Lazarusie nie można zapisać do zmiennej double wartości integer?
Ale typ integer można bez problemu zapisać do double.

Te dwa zdanie dotyczą tego samego. W Delphi nie ma takiej potrzeby, w Lazarusie nie wiem dlatego zapytałem. Jeśli nie jest to wymagane a powoduje błąd to można to pominąć.

0

Te dwa zdanie dotyczą tego samego. W Delphi nie ma takiej potrzeby, w Lazarusie nie wiem dlatego zapytałem. Jeśli nie jest to wymagane a powoduje błąd to można to pominąć.
Jak to pominąć
A[0,0]:= N1;
kiedy tutaj jest
Write(Plik,A[0,0],A[0,1],A[0,2]);

1

Panowie, ale czy to taki problem, żeby zamiast snuć teorie po prostu sprawdzić, jak się Lazarus zachowa? :P


procedure TForm1.Button1Click(Sender: TObject);
var calkowita: integer;
    zmiennoprzecinkowa: extended;
begin
  calkowita := 24234;
  zmiennoprzecinkowa := 0.2434435;
  zmiennoprzecinkowa := zmiennoprzecinkowa + calkowita;
  showmessage (FloatToStr(zmiennoprzecinkowa));
end;             

0

Wpis
" A[0,0]:= N1(+0.0);
W instrukcji A[0,0]:= N1(+0.0); pojawia się wspomniany wcześniej błąd
W komentarzu jest próba zamiany zmiennej N1 - Integer na Double aby dopasować A[0,0]:= N1+0.0; bez zmian - błąd

W programie głównym jest identyczne podstawienie i błędu nie ma
A[0,0]:= N1; A[0,1]:= 0.0; A[0,2]:= 0.0; "

wyraźnie sugeruje że błąd jest w A[0,0]:= N1(+0.0); chyba że ja jakoś inaczej czytam. Nigdzie nie pisałeś że chodzi o

Write(Plik,A[0,0],A[0,1],A[0,2]);

@cerrato, nie mam Lazaura żeby sprawdzić a nie chce mi się instalować.

1

nie mam Lazaura żeby sprawdzić a nie chce mi się instalować.

Tak się fajnie składa, że akurat mam jednego przy sobie, więc szybko sprawdziłem :D

Podany powyżej kod się kompiluje bez problemów, a wartość zwrócona przez ShowMessage jest zgodna z tym, czego chcemy (mówiąc wprost - ładnie się dodał integer do float'a i mamy wartość zmiennoprzecinkową o takiej wartości, jaka wynika z sumowania). Nie trzeba żadnych czarów czy czarnej magii odprawiać ;)

0

Tak czy inaczej jest błąd
Załączam ostatnią wersję procedur DyskWrit i DyskRead

{ Procedura zapisuje w pliku "Nazwa.*" wyniki obliczeń z programu
SCRATONUR:}
Procedure DyskWrit (N1: Integer; A: Wek);
Var
Nazwa: String[15];
Plik: File of Double;
Begin
Readln;
Write('Podaj nazwe zbioru na dysku np. = C:\Silnik.10 '); Readln(Nazwa);
Nazwa:=Concat('C:',Nazwa);
Assign(Plik,Nazwa);
Rewrite(Plik);
A[0,0]:= N1;
Write(Plik,A[0,0],A[0,1],A[0,2]);
For k:=1 To N1 Do
For l:=0 To 2 Do
Write(Plik,A[k,l]);
Close(Plik)
End; //Dyskwrit

{Procedura odczytuje z pliku "Nazwa.*" wyniki obliczeń z programu
SCRATONUR: N= liczba pomiarów, x= z, Y[1] = p, Y[2] = t}
Procedure DyskRead;
Var
k, l: Integer;
N1: Integer;
Nazwa: String[15];
Plik: File of Double;
Begin
Write('Podaj nazwe zbioru na dysku np. = C:\Silnik.10 '); Readln(Nazwa);
Nazwa:=Concat('C:',Nazwa);
Assign(Plik,Nazwa);
Reset(Plik);
Read(Plik, A[0,0]);
N1:= Round(A[0,0]);
For k:=1 To N1 Do
For l:=0 To 2 Do
Read(Plik,A[k,l]);
Close(Plik);
ClrScr;
Writeln(#10,'Liczba pomiarów N= ',N1,#10,#13);
For k:=0 To N1 Do Writeln('z= ',A[k,0],' p=',A[k,1],' t=',A[k,1]);
End;

1

utwórz folder na dysku C i spróbuj w nim utworzyć swój plik. Windows 10 nie lubi gdy tworzy się pliki w ścieżce C:\

0

Dziękuję wszystkim za pomoc w rozwiązaniu problemu.
Program działa bezbłędnie ale nie mam pojęcia dlaczego. Jakby za sprawą tajemniczego przełącznika zniknęły błędy i program działa.

Teraz czeka mnie analiza wyników. Na pierwszy rzut oka jedne wyniki są 10-krotnie większe a inne 1000 - krotnie . Może popełniłem błąd w przeliczaniu jednostek (kG, G, kGm, J itp)

0

Czy możesz napisać, co było ostatnią rzeczą, którą zmieniłeś, zanim zaczęło działać?

Prawdopodobnie to może mieć duży związek z faktem, że program się "naprawił" ;)

0

Chodzi oto,że stało się to bez mojego udziału.

0

Czy chcesz powiedzieć, że teraz jak weźmiesz sobie listing z pierwszego posta, wkleisz do środowiska to się skompiluje, uruchomi i zadziała zgodnie z oczekiwaniami?

0
cerrato napisał(a):

Czy chcesz powiedzieć, że teraz jak weźmiesz sobie listing z pierwszego posta, wkleisz do środowiska to się skompiluje, uruchomi i zadziała zgodnie z oczekiwaniami?

Nie zadziała ponieważ po drodze były inne zmiany. Błędy które wtedy występowały nie pozwalały nawet skompilować programu.

0

No właśnie :D

Czyli program się sam magicznie nie "uzdrowił", tylko jakoś grupowo go poprawiliśmy i uzyskaliśmy działająca wersję. Nie ma (niestety, bo nieraz by się przydał) żadnego " tajemniczego przełącznika".

0
cerrato napisał(a):

No właśnie :D

Czyli program się sam magicznie nie "uzdrowił", tylko jakoś grupowo go poprawiliśmy i uzyskaliśmy działająca wersję. Nie ma (niestety, bo nieraz by się przydał) żadnego " tajemniczego przełącznika".

Sam i magicznie mam nadzieję, że na zawsze.
Jeszcze muszę usunąć niepotrzebne wyświetlania danych pośrednich ale to po analizie wyników.
Sądzę że można już zamknąć wątek. A może podesłać Ci ostateczną wersję programu. Tylko jaką *.pas czy *.exe

0

Może nie tyle mi, co daj jako załącznik (analogicznie do pierwszego posta). Wrzuć wersję PAS, zobaczymy czy się skompiluje ;)

0

Załącznk

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