-321oho napisał(a)
Serio, ile razy można się powtarzać że błąd leży w procedurze wyświetlającej i dodającej elementy? Co do użycia debuggera, to mam pewne wątpliwości czy ty byś temu podołał bo problem był bardzo paskudny i z całą pewnością pytacz by mu nie podołał (sam musiałem paręnaście minut siedzieć nad tym).
Ależ najmniejszego problemu nie miałem, żeby znaleźć błąd, szczególnie z tak wspaniałym narzędziem jakim jest debuger; Dodałem sobie do Watches
zmienne I
, J
, a także trzy pierwsze elementy macierzy Magazyn
: Magazyn[1]
, Magazyn[2]
i Magazyn[3]
; Dzięki temu od razu zauważyłem, że dodając pierwszy artykuł do macierzy nie ląduje wcale w Magazyn[1]
, tylko w Magazyn[2]
właśnie przez tą konstrukcję: var magazyn : array of artykul)
; Wystarczyło stworzyć sobie typ, np.: TMagayn = array [1 .. 1000] of Artykul;
i ustawić argument w tej procedurze nowego typu, ale oczywiście kto by posłuchał, żeby indeksować macierze od 0
- lepiej nic o tym nie pisać; Poza tym denerwowały mnie deklaracje typów nie zaczynających się prefiksem T
, więc je zmieniłem; Kod nieznacznie zmodyfikowany poniżej:
Kopiuj
program Project1;
uses
Crt;
type
TDzialy = (Elektryka, Hydraulika, Narzedzia, Art_metalowe, Materialy, Inne);
type
TJednostki = (Sztuk, Metr, Kg, Litr);
type
TArtykul = packed record
Nazwa: String[20];
Dzial: TDzialy;
Jednostka: TJednostki;
Ilosc: Integer;
Max: Integer;
Cena: Double;
Dostepnosc: Boolean;
end;
type
TMagazyn = array [1 .. 1000] of TArtykul;
var
Magazyn: TMagazyn;
Klawisz: Char;
I, J: Integer;
Plik: File of TArtykul;
procedure Nowy(var AMagazyn: TMagazyn);
begin
ClrScr;
WriteLn('Dodawanie nowego artykulu: ');
WriteLn;
Write('Podaj nazwe artykulu: ');
ReadLn(AMagazyn[I].Nazwa);
Write('Cena za jednostke: ');
ReadLn(AMagazyn[I].Cena);
WriteLn('--- Dodano nowy artykul do sklepu ---');
WriteLn('Wcisnij dowolny klawisz...');
ReadKey;
end;
procedure Wyswietl(AMagazyn: TMagazyn);
begin
ClrScr;
WriteLn('Wszystkie artykuly w sklepie: ');
WriteLn;
for J := 1 to I do
begin
WriteLn('-------------------------------------');
WriteLn('Nazwa: ', AMagazyn[J].Nazwa);
WriteLn('Cena: ', AMagazyn[J].Cena:2:2);
end;
WriteLn('B - powrot do glownego menu');
repeat
ReadLn(Klawisz);
until (Upcase(Klawisz) = 'B');
end;
begin
I := 0;
repeat
ClrScr;
WriteLn('N - Nowy artykul');
WriteLn('W - Wyswietl wszystkie artykuly');
WriteLn('R - Wczytaj');
WriteLn('S - Zapisz');
WriteLn('Q - Koniec');
ReadLn(Klawisz);
if UpCase(Klawisz) = 'N' then
begin
Inc(I);
Nowy(Magazyn);
end;
if UpCase(Klawisz) = 'W' then
Wyswietl(Magazyn);
if UpCase(Klawisz) = 'S' then
begin
ClrScr;
AssignFile(Plik, 'C:\Plik.dtb');
try
ReWrite(Plik);
for J := 1 to I do
Write(Plik, Magazyn[J]);
finally
CloseFile(Plik);
end;
WriteLn('Zapisano do pliku.');
WriteLn;
WriteLn('Wcisnij dowolny klawisz...');
ReadKey;
end;
if UpCase(Klawisz) = 'R' then
begin
ClrScr;
AssignFile(Plik, 'C:\Plik.dtb');
try
Reset(Plik);
I := FileSize(Plik);
for J := 1 to I do
Read(Plik, Magazyn[J]);
finally
CloseFile(Plik);
end;
WriteLn('Odczytano baze z pliku. Wcisnij dowolny klawisz...');
ReadKey;
end;
until UpCase(Klawisz) = 'Q';
end.
I całość działa bez zarzutu, sprawdzałem na wiele sposobów i nie znalazłem błędu; Odnalezienie błędu w kodzie pytacza zajeło mi ~5 minut właśnie dzięki debugerowi;
-321oho napisał(a)
No ale gdzie ja, ty jesteś nieprzemakalny
No oczywiście ja jestem zły, bo przedstawiłem ludzki sposób podziału programu na procedury, bo zmodyfikowałem identyfikatory typów, zmiennych i procedur, bo przeinaczyłem zmienne globalne na lokalne tylko dla potrzeb konkretnych procedur, bo w ogóle miałem czelność przedstawić kod, który sam bym wykorzystał i który wiem, że spełni założenia; Jestem ciekam co by było gdybym jeszcze zaimplementował macierze dynamiczne - wtedy to już w ogóle byłbym śmieciem, bo miałem czelność przedstawić coś, czego Ty nie podałeś; Dziwię Ci się, że zamiast opierdolić pytacza za stosowanie złych praktych Ty opiepszasz mnie za to, że udzieliłem kilku wskazówek co do budowy programu, formatowania, nazewnictwa itd.
-321oho napisał(a)
wciąż mówisz jak to ładnie użyłeś czegoś tam kiedy właściwie miejscami napisałeś gorzej to co pytacz (while not eof(f) do jest lepsze niż jakieś for i praktycznie każdy kurs wskazuje taką konstrukcję)
Napisz mi w czym pętla for
jest gorsza od while
- według mnie to nie ma różnicy, jednak while
nigdy do takich zastosowań nie zaprzęgałem, więc nie mam 100% pewności co do jej zachowania; Być może masz rację, bo przecież ja nie potrafię programować i nie mam 20-letniego stażu w poważnej firmie, stąd każdy mój algorytm jest albo błędny, albo w ogóle nie optymalny; Co do kursu - ja uczyłem się z książki Adama Boducha oraz z tego artykułu, ale widać autor książki też nic na ten temat nie wie;
-321oho napisał(a)
Zrobiłeś zupełnie nowy kod w którym inaczej niż pytacz przekazujesz parametry do procedur.
Dokładnie po to, żeby pokazać pytaczowi, że istnieją inne sposoby na wykonanie róznych elementów tego programu, jak właśnie wymienione przekazywanie argumentu do tych procedur; W tym algorytmie nie zawarłem wszystkiego, co jest w programie pytacza, bo to nie gotowiec; Poza tym dodać pozostałość to kwestia kilku minut;
-321oho napisał(a)
Wiesz co? Pokaż mi pytacza który naprawisz modyfikując procedury zapisu i odczytu. Ciekaw jestem czy ci się uda, a jeżeli ci się uda to sam zobaczysz że błąd nie leży na dobrą sprawę w procedurze zapisu i odczytu tylko w reszcie rzeczy.
Aby do tego dojść wystarczył debuger i chwilka na postawienie breakpoint'ów i dodanie kilku zmiennych do okna Watches
- tyle wystarczyło żeby móc odpowiedzieć na pytanie autora wątku; Ja najpierw zasugerowałem błąd właśnie w procedurze odczytu i pomyliłem się, bo niedokładnie przeanalizowałem kod; Następnie jak tylko wróciłem do komputera skopiowałem kod do edytora, przetestowałem, zobaczyłem że jest bug, podpiąłem debuger i go moment znalazłem; Reszta informacji które podałem przysłużą się do poprawienia algorytmu;
I nic do tego nie ma deklaracja łąńcucha w strukturze, bo nie ma znaczenia na pracę algorytmu czy to jest String[20]
, czy ShortString[2]
, i tak będzie działać po przeinaczeniu argumentów;
A tak nawiasem:
-321oho napisał(a)
maniek099 napisał(a)
Podczas odczytywania pętla wykonuje się 4 razy (bo później przy wyświetlaniu, wyświetla 4 rekordy, czyli i=4) ale ostatni rekord jest pusty;/
A próbowałeś z Debuggerem?
-321oho napisał(a)
Co do użycia debuggera, to mam pewne wątpliwości czy ty byś temu podołał bo problem był bardzo paskudny i z całą pewnością pytacz by mu nie podołał
Skoro wątpisz, że ten problem jest do znalezienia używając debugera (a bardzo łatwo jest go dzięki temu narzędziu znaleźć), to po co każesz mu go używać? Sam sobie przeczysz;