[Pascal] Błąd przy ponownym tworzeniu pliku

0

Witam!

Piszę właśnie program, którego ustawienia są zapisywane do pliku i będzie możliwość wyboru jednego z nich.
Pliki tworzone są na dwa sposoby:
1.) poprzez automat, który przekazuje nazwę do procedury tworzącej plik: NewFile('JakasNazwaPliku');
2.) po podaniu nazwy przez użytkownika - wywołuje się: NewFile('spytaj o nazwe);

Kod mojej procedury wygląda po części tak:

PROCEDURE NewFile(nazwa:string);
var nowaNazwa :string;
	
Begin
    If nazwa = 'spytaj o nazwe' then
        begin
         ClrScr;
         GoToXY(5,5);   Write('Podaj nazwe pliku:');
         GoToXY(25,5);  Read(nowaNazwa);
        end
    Else nowaNazwa := nazwa;

Gdzie tkwi problem?

Odpalam program i tworzę plik przy ręcznym podaniu nazwy. Wszystko gra. Jednak kiedy próbuję po raz drugi utworzyć plik to pojawia mi się błąd:

    Podaj nazwe pliku:  Runtime error 5 at $000022D8
  $000022D8  NEWFILE,  line 186 of /Users/macdada/programowanie/EverydayToDos/EverydayToDos.pas
  $000026A4  main,  line 254 of /Users/macdada/programowanie/EverydayToDos/EverydayToDos.pas
  $0000194C of EmptyPlaceHolderUnit.pas
  $00001650 of EmptyPlaceHolderUnit.pas

Dodam, że używam FreePascalCompilera zintegrowanego z pakietem XCode na Mac OS X 10.4.10 (choć to chyba w tym przypadku nie ma znaczenia).

Linia 186:
Rewrite(nowyPlik);

Linia 254:
NewFile('spytaj o nazwe');

Prośba o podanie nazwy pliku znajduje się w linii 178. Dowodzi to temu, że przy drugiej próbie utworzenia pliku jest ona pomijana i program od razu chce utworzyć plik ignorując (?) sekcję If...

Ponowne uruchomienie programu pozwala nowy plik utworzyć lecz przy drugiej próbie znowu pojawia się błąd.

DLACZEGO? CO MAM ZMIENIĆ, ŻEBY DZIAŁAŁO?
Bardzo proszę o pomoc - niestety nie znam nikogo "w realu" kto mógłby mi pomóc, choć pewnie wytłumaczyć o co chodzi byłoby łatwiej ;)

Pozdr.
Dawid, MacDada

0

Postanowiłem opublikować cały kod... A co mi - przecież i tak piszę to dla zabawy i nauki :D
Jeszcze wiele niezrobione, kod jest chaotyczny i niekiedy bezsensowny, ale mam nadzieję, że opublikowanie go coś da ;)
Część kodu może Wam się nie skompilować, bo jest tworzona pod FCP dla MacOSXa.

PROGRAM DoZrobienia;

USES
    EmptyPlaceHolderUnit,
    Crt;


TYPE
 TdostepnePliki = record
    liczba :byte;
    aktualny :string;
    nazwa :array [1..10] of string;
 end;

 Tzadanie = record
    nazwa, opis :string;
    id, pozycja :byte;
    wykonania :array [1..2] of byte;
    { 1 to liczba zrobionych, a 2 mozliwych do zrobienia } 
 end;



{ zmienne globalne }
VAR
 listaPlikow :file of TdostepnePliki;
 dostepnePliki :TdostepnePliki;
 pliczek :file of Tzadanie;
 zadanie :Tzadanie;
 zadania :array [1..10] of Tzadanie;
 klawiszmenu :char;



{ Wypisuje dany znak okreslona liczbe razy }
PROCEDURE PiszZnak(liczbaznakow:byte ; znaczek:char);
var i:byte;
begin
	for i := 1 to liczbaznakow do write(znaczek);
end;

PROCEDURE WriteXY(wspX,wspY:byte ; napis:string);
begin
    GoToXY(wspX,wspY);
    Write(napis);
end;

PROCEDURE RysujRamke;
var i:byte;
begin
{	PiszZnak(80,'*');
	
	for i:=1 to 22 do
	  begin
	  WriteLn;
	  write('*'); PiszZnak(78,' '); write('*');
	  end;
	
	writeln;
	PiszZnak(80,'*'); }
end;


{ Obsluga plikow }

PROCEDURE UtworzPlik;
begin    
    zadanie.id :=1;
    zadanie.nazwa :='Zadanie domyslne';
        
  { zapisz zadanie do pliku }
    Rewrite(Pliczek);
    Write(Pliczek, zadanie);    
    Close(Pliczek);
end;


FUNCTION LiczbaZadan:byte;
var i :byte;
begin
    i :=1;
    Reset(Pliczek);
    while not Eof(Pliczek) do
        begin
         Read(Pliczek,zadanie);
         Inc(i);
        end;
    Close(Pliczek);
    LiczbaZadan :=i-1;
end;    


PROCEDURE DopiszZadanie;
var j:byte;
begin
    j :=LiczbaZadan;
    zadanie.id :=LiczbaZadan+1;
        
    ClrScr; 
    Write('Podaj nazwe zadania: ');
    ReadLn(zadanie.nazwa);
    
    { dopisz zadanie do pliku }
    Reset(Pliczek);
    Seek(Pliczek, j);
    Write(Pliczek, zadanie);
    Close(Pliczek);
end;

PROCEDURE OdczytDanych;
var ktoreid :byte;
begin
    ClrScr;
    
    WriteLn('Liczba zadan to ', LiczbaZadan);
    WriteLn('Podaj ID zadania do wyswietlenia (9 pokazuje wszystkie): ');
    Read(ktoreid);
    
    ClrScr;
    Reset(Pliczek);
    IF ktoreid<>9 THEN
        begin
            Seek(Pliczek, ktoreid-1); // bo 0 jest zadaniem pierwszym
            Read(Pliczek, zadanie);
            Write(zadanie.id,' ',zadanie.nazwa);
        end
    ELSE while not Eof(Pliczek) do
        begin
            Read(Pliczek, zadanie);
            Write(zadanie.id,' ',zadanie.nazwa);
            WriteLn;
        end;
    Close(Pliczek);
    ReadKey;
end;


PROCEDURE LoadFile;
var i :byte;
Begin
    
    Reset(listaPlikow);
    Read(listaPlikow, dostepnePliki);
    Close(listaPlikow);
    
    ClrScr;
    RysujRamke;
    WriteXY(5,3,'Aktualny plik to "');
    WriteXY(23,3,dostepnePliki.aktualny);
    WriteXY(23+length(dostepnePliki.aktualny),3,'"');
    
    WriteXY(5,5,'Dostepne pliki to:');
    
    for i:=1 to dostepnePliki.liczba do
    begin
        WriteXY(10,5+i, dostepnePliki.nazwa[i]);
    end;
    
    ReadKey;
    
End;


PROCEDURE NewFile(nazwa:string);
var
	sciezka, nowaNazwa, sciezkaNazwa :string;
	nowyplik :file of Tzadanie;
	
Begin
	
    If nazwa = 'spytaj o nazwe' then
        begin
         ClrScr;
         RysujRamke;
         WriteXY(5,5,'Podaj nazwe pliku:');
         GoToXY(25,5); Read(nowaNazwa);
        end
    Else nowaNazwa := nazwa;
	
	sciezka :='Library/Preferences/DoZrobienia/';
	sciezkaNazwa :=sciezka+nowaNazwa;
	Assign(nowyPlik, sciezkaNazwa);
	Rewrite(nowyPlik);
	Close(nowyPlik);
    
    Reset(listaPlikow);
    Read(listaPlikow, dostepnePliki);
    Close(listaplikow);
    Inc(dostepnePliki.liczba);
    dostepnePliki.nazwa[dostepnePliki.liczba] := nowaNazwa;
    dostepnePliki.aktualny := nowaNazwa;
    Reset(listaPlikow);
    Write(listaPlikow, dostepnePliki);
    Close(listaplikow);
	
End;



PROCEDURE PlayTheGame;
Begin

	

End;




{ ---- POCZATEK ---- }
BEGIN

Assign(listaPlikow, 'Library/Preferences/DoZrobienia/ListaPlikow');

{ tworzenie listy plikow przy instalacji}
{$I-} Reset(listaPlikow); {$I+}
if IOResult=2 then
    begin
        Close(listaPlikow);
        dostepnePliki.liczba :=0;
        Rewrite(listaPlikow);
        Write(listaPlikow , dostepnePliki);
        Close(listaPlikow);
        NewFile('przyklad');
    end;



{ menu glowne }	
REPEAT

    Reset(listaPlikow);
    Read(listaPlikow , dostepnePliki);
    Close(listaPlikow); 
  
    ClrScr;
    RysujRamke;
        WriteXY(5,3,'Aktualny plik to "');
        WriteXY(23,3,dostepnepliki.aktualny);
        WriteXY(23+length(dostepnepliki.aktualny),3,'"');
    WriteXY(5,5,'1. Odpal plik');
    WriteXY(5,6,'2. Wczytaj plik');
    WriteXY(5,7,'3. Nowy plik');
    WriteXY(5,8,'4. Koniec');
     GoToXY(5,9);
     klawiszmenu :=ReadKey;
     
    Case klawiszmenu of
        '1':PlayTheGame;
        '2':LoadFile;
        '3':NewFile('spytaj o nazwe');
        '4':Exit;
    End;

UNTIL 1=2;
	
END.
0

a sprawdź czy nie pomoże zamiana Read(nowaNazwa); na ReadLn(nowaNazwa);

poza tym - uzyj debugera, postaw breakpoint na początku procedury sprawiającej problemy i prześledź kod krok po kroku.

0

ŁF - WIELKIE DZIĘKI.
ReadLn zamiast Read pomogło, choć nie mam pojęcia dlaczego ;-)

W każdym razie napisałem prościutki program dla testu:

PROGRAM test;

USES
    EmptyPlaceHolderUnit,
    Crt;

VAR
    napis :string;


BEGIN

    ClrScr;
    Write('Podaj napis po raz pierwszy: ');
    Read(napis);
    Write('Podales: ');
    Writeln(napis);

    Writeln;
    Write('Podaj napis po raz drugi: ');
    Read(napis);
    Write('Podales: ');
    Writeln(napis);
	
END.

Co się okazuje? Po porstu za drugim razem nie pyta mnie o napis. Podczas wykonywania wygląda to tak:

Podaj napis po raz pierwszy: test
Podales: test

Podaj napis po raz drugi: Podales: 
logout
[Process completed]

Dwie ostatnie linijki są dodawane na końcu każdego programu w Terminalu (konsoli) Mac OS X-a.

Tak czy siak, BigThanks bo mogę pisać dalej bez kombinowania (już chciałem tablicę robić, żeby za każdym razem wczytywać pod inną zmienną :D)

Pozdr.
Dawid, MacDada

0

bo pierwsze read nie czyta znaku końca linii, więc dostawało go następne read, a nie możesz utworzyć pliku o nazwie #13.

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