Szyfr cezara w Delphi

0

Witam, mój problem polega na tym, że program jaki piszę czyli szyfrowanie Cezara radzi sobie z tekstem tylko do 2 znaków, moim zdaniem składnia jest dobra i nie wiem na czym może polega błąd. Proszę o pomoc lub jakieś wskazówki. Podaję procedurę która jest odpowiedzialna za zamianę danych.

 
procedure TForm1.Button1Click(Sender: TObject);
var tab:array[1..50]of integer;
var koniec,i,j:integer;
var zn:string;
const tab2:array[1..25]of string =(('a'),('b'),('c'),('d'),('e'),('f'),('g'),('h'),
('i'),('j'),('k'),('l'),('m'),('n'),('o'),('q'),('p'),('r'),('s'),('t'),('u'),('w'),
('x'),('y'),('z'));
begin
edit1.Clear;
edit2.Clear;
edit3.Clear;
edit4.Clear;
edit5.Clear;
koniec:=length(memo1.Text );
edit2.Text :=inttostr(koniec);
for i:=1 to koniec do begin
  edit5.Text:=edit5.Text +inttostr(i)+',';
  zn:=copy(memo1.Text,i,i);
  edit4.Text :=edit4.Text +zn+',';
    for j:=1 to 25 do begin
      if(zn=tab2[j])then begin
        if(j+3>25)then tab[i]:=(25-(j+3))*(-1)
        else tab[i]:=j+3;
        end;
    end;
end;
    for i:=1 to koniec do begin
    edit1.Text :=edit1.text+tab2[tab[i]];
    edit3.Text :=edit3.Text +inttostr(tab[i])+'0';
    end;


end;

Poszczególne edity są po to abym sam doszedł do tego co się dzieje z danymi ale nie udało się, z góry dzięki za pomoc:D

1

Proszę o pomoc lub jakieś wskazówki.

Wskazówka: użyj debuggera. Lepsze to niż jakieś lamerskie edity.

0

Nie chce mi się nawet analizować tego kodu (?) na początek przeczytaj jak działa Copy http://4programmers.net/delphi/copy

0

kAzek - sory ale nie rozumiem tego co napisałeś. Zmienna zn jest to każda z kolei litera z memo1, która jest sprawdzana czy występuje w mojej tablicy znaków (tab2), wtedy zostaje zamieniona na liczbę (czyli indeks od tab2) i zostaje powiększona o 3 (bo tak działa ten szyfr). Przy wypisywaniu działa to na odwrót czyli powiększona już liczba o 3 jest zamieniana na znak z tablicy znaków (tab2) i wypisana.

0

Nie w tej chwili kopiujesz do zmiennej zn i znaków od i-tego np. masz tekst
"przykład" a zmienne i wynosi 3
to kopiuje ci do zmiennej zn ciąg "zyk"
chcąc pobrać jeden znak ze stringa (memo1.Text zwraca string) wystarczy zmienna zn typu Char a znak pobierasz
zn:= Copy(Memo1.Text, i, 1);
albo lepiej po prostu:
zn:= Memo1.Text[i];

0

OK, rozumiem, wprowadzę zmiany i zobaczę jak działa po czym dam odp co i jak :D

0

kAzek - dzięki wielkie za wskazówkę, teraz w pełni działa poprawnie, czułem, że gdzieś tam leży źródło ale nie wiedziałem, że źle zastosowałem copy bo taki sposób znalazłem gdzieś tutaj na forum, jeszcze raz dzięki :D

1
TekMast napisał(a):
const tab2:array[1..25]of string =(('a'),('b'),('c'),('d'),('e'),('f'),('g'),('h'),
('i'),('j'),('k'),('l'),('m'),('n'),('o'),('q'),('p'),('r'),('s'),('t'),('u'),('w'),
('x'),('y'),('z'));

Skoro tab2 ma być tablicą pojedynczych znaków, to prawidłowo należało ją zadeklarować:

const tab2:array[1..25] of Char = (('a'),('b'),('c'),('d'),('e'),('f'),('g'),('h'),
('i'),('j'),('k'),('l'),('m'),('n'),('o'),('q'),('p'),('r'),('s'),('t'),('u'),('w'),
('x'),('y'),('z'));

lub prostszy zapis:

const tab2:array[1..25] of Char = ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','q','p','r','s','t','u','w','x','y','z');

A ponieważ typ string możemy traktować jako tablicę znaków, można deklarację jeszcze uprościć:

const tab2='abcdefghijklmnoqprstuwxyz';
1

Można w ogóle wykluczyć tą statyczną macierz; Jeśli chodzi o ten kod:

for i:=1 to koniec do begin
  edit5.Text:=edit5.Text +inttostr(i)+',';
  zn:=copy(memo1.Text,i,i);
  edit4.Text :=edit4.Text +zn+',';
    for j:=1 to 25 do begin
      if(zn=tab2[j])then begin
        if(j+3>25)then tab[i]:=(25-(j+3))*(-1)
        else tab[i]:=j+3;
        end;
    end;
end;

oczywiście sformatowany po ludzku:

for I := 1 to Koniec do
begin
  Edit5.Text := Edit5.Text + IntToStr(I) + ',';
  Zn := Copy(Memo1.Text, I, I);
  Edit4.Text := Edit4.Text + Zn + ',';

  for J := 1 to 25 do
  begin
    if(Zn = Tab2[J]) then
    begin
      if(J + 3 > 25) then
        Tab[i] := (25 - (J + 3)) * (-1)
      else
        Tab[i] := J + 3;
    end;
  end;
end;

możnaby uprościć; Nie bardzo rozumiem co ten kod ma zamiar wykonywać, ale według mnie powinien sprawdzić, czy znak przechowywany w zmiennej Zn istnieje w macierzy Tab2 (gratuluję nazewnictwa...) i jeśli tak - oblicza mu nową wartość przez zwiększenie jego kodu ASCII o 3 (a tym samym przesunięcie znakowe o 3 miejsca w prawo (!)); Obliczanie wykonane zostaje na tej zasadzie, że gdy na wejściu pojawi się znak x, y lub z (czyli licznik się przekręci) - zostaną mu przyporządkowane znaki odpowiednio a, b lub c;

Według mnie deklaracja i definicja macierzy jest niepotrzebna, dlatego że prościej jest porównać znak ze zbiorem, a do obliczeń wykorzsytać kod ASCII; Poza tym zmienna Zn nie powinna być typu String (!), tylko Char lub Byte - jak kto woli;

Czyli zamiast pierwotnej pętli można zastosować taką konstrukcję (dla Zn: Byte):

for I := 1 to Koniec do
begin
  Edit5.Text := Edit5.Text + IntToStr(I) + ',';
  Zn := Ord(Copy(Memo1.Text, I, 1)[1]);
  Edit4.Text := Edit4.Text + Chr(Zn) + ',';

  if Zn in [{a} 97 .. {z} 122] then
    if Zn + 3 > 122 then
      Tab[I] := Zn - 119
    else
      Tab[I] := Zn - 96;
end;

i będzie działać bezproblemowo; Dzięki wykorzystaniu kodu ASCII danego znaku możesz ominąć deklarację macierzy Tab2; W tej pętli znajduje się rozwiązanie jednego problemu, dla którego wcześniej Ci nie działało, ale musisz go odnaleźć sam; Tak jak wspomniał -123oho - użyj debuggera a znajdziesz pozostałe bugi (jeżeli takowe istnieją);

Do tego macierz Tab powinna być typu Byte - oszczędzaj pamięć;

Dodatkowo dopowiem, że nie możesz szybko znaleźć błędów bo kod wygląda tragicznie - brak sensownie wykorzystywanych wcięć, brak zastosowania stylu wielbłądziego czy notacji węgierskiej, begin'y pozostawione w jednej linii z definicją warunku czy pisanie wszystkiego na kupę bez odstępów w postacji jednego znaku spacji (w odniesieniu do operatorów); To wszystko sprawia, że czytelność kodu jest niska i znacznie utrudnia jego interpretację; Zastanów się nad tym;

0

To czy ja piszę kod z beginem w lini z warunkiem czy niżej, to jest tylko i wyłącznie kwestia tego, jak kto lubi. Ja tak piszę od zawsze, tobie może to przeszkadzać, mnie wgl a wręcz może mi być to bardziej na rękę. To, że piszę program w ten sposób to tylko i wyłącznie moje chciejstwo i oczywiście twój sposób jest szybszy i oszczędniejszy ale postanowiłem tak napisać program, piszę to dla siebie dla poćwiczenia, ponieważ chodzę do szkoły informatycznej a takich programów do pisania jeszcze nie miałem więc chciałem sprawdzić siebie. Skoro już wiesz, że jestem jeszcze uczniem to pewnie domyślasz się, że nie wiem o co chodzi z tymi stylami, węgrami itp ;D Tablica była typu string choć powinna być char ale to nie jest błąd przez który program był wadliwy, to było coś co pisałem kilkanaście minut a nie nie wiadomo ile więc optymalizacją kodu się wgl nie przejmowałem. Program działa, co miałem to poprawiłem, twoja odpowiedź również była pouczająca (choć może trochę za bardzo :D), doceniam i dziękuje. Pozdrawiam.

4

To czy ja piszę kod z beginem w lini z warunkiem czy niżej, to jest tylko i wyłącznie kwestia tego, jak kto lubi.

Nie, są standardy dobrego kodu.

Ja tak piszę od zawsze, tobie może to przeszkadzać, mnie wgl a wręcz może mi być to bardziej na rękę.

Tutaj kodu nie piszesz dla siebie ale dla nas.

To, że piszę program w ten sposób to tylko i wyłącznie moje chciejstwo i oczywiście twój sposób jest szybszy i oszczędniejszy ale postanowiłem tak napisać program, piszę to dla siebie dla poćwiczenia, ponieważ chodzę do szkoły informatycznej a takich programów do pisania jeszcze nie miałem więc chciałem sprawdzić siebie.

To że to twój program nie zmienia tego że my go czytamy. Ja jak zobaczyłem kod to nie chciałem go analizować, olałem.

Skoro już wiesz, że jestem jeszcze uczniem to pewnie domyślasz się, że nie wiem o co chodzi z tymi stylami, węgrami itp ;D

Nieznajomość prawa nie zwalnia z niego.

Tablica była typu string choć powinna być char ale to nie jest błąd przez który program był wadliwy, to było coś co pisałem kilkanaście minut a nie nie wiadomo ile więc optymalizacją kodu się wgl nie przejmowałem.

Optymalizacja to coś innego niż poprawne typy danych. Twoje tłumaczenia są beznadziejne.

Ja osobiście dziwię się że koledzy w ogóle bawią się w analizę i poprawianie aż tak nieczytelnego kodu. IMO lepiej gościowi dać link i niech poprawia kod jeżeli chce żebyśmy go analizowali. Będzie zysk dla pytacza bo się kod nauczy pisać i dla nas bo nie będzie trzeba się bawić w analizę nieczytelnego kodu.

1
TekMast napisał(a)

Jeśli zauważyłeś na czym mój problem polegał, a nie masz sił lub chęci na analizę mojego kodu to się za to nie bierz.

Skoro ktoś otwiera ten wątek i analizuje jego treść to świadczy o tym, że jest chetny pomóc; Jeśli zaś opis problemu jest nędzny merytorycznie oraz formatowanie kodu znacznie utrudnia jego interpretację to nie dziw się, że nikomu nie chce się szukać błędów; Bądź wdzięczny za to, że ktokolwiek poświęcił czas na odszukanie błędów których mógłbyś uniknąć, gdybyś raczył wcześniej poczytać jakikolwiek kurs programowania w tym języku; Wiedziałbyś wtedy, że formatowanie kodu to standard, który oczywiście można przestrzegać, ale prawie każdy "po swojemu" piszę kod; Jednak Twój kod jest jak najbardziej nieczytelny i nie dziw się, że spotkałeś się z krytyką w tym kierunku; Gdybyś przeszukał forum pod kątem właśnie formatowania kodu to zauważyłbyś, że większość kodów (nawet jeśli są wysoce efektywne) napisanych w głupkowatym stylu została zkrytykowana za to, że trudno jest go zrozumieć nawet doświadczonemu programiście; Bardzo dużo kodów w postach jest napisanych byle jak, jednak gdyby było inaczej odpowiedzi było by więcej i pojawiałyby się szybciej; Oszczędzony byłby czas pomagającego, a nie każdy ma pół dnia na mozolną analizę po to, by leniowi i kodowemu niechlujowi pomóc znaleźć bugi;

TekMast napisał(a)

Jest to program amatorski, prosiłem o pomoc, o to żeby działał.

Nawet jeśli to jest kod jednorazowego użytku to warto pisać go od razu zoptymalizowany - dzięki temu od początku będziesz się uczył dobrych praktyk i każdy następny napisany kod będzie lepszej jakości; Tak się uczy kombinowania i upraszczanie sobie pracy; Po to właśnie początkującym programistom wbija się do głowy reguły DRY i KISS, żeby od pierwszych dni uczyli się pisać krótkie, zwięzłe i efektywne kody; Każdy kiedyś zaczynał, każdy pisał beznadziejne programy, które można było zoptymalizować o dziesiątki procent i każdy, kto wie co to znaczy będzie Ci doradzał wykorzystanie prostych mechanizmów skracających kod i przyspieszających jego działanie; Nie dziw się, że będziesz za to krytykowany, ale zaczynając przygodę z programowaniem warto przeczytać dobrą książkę czy kurs z sieci i od razu wpajać sobie dobre nawyki i optymalizacyjne sztuczki; Potem będziesz je stosował na bieżąco i nie będzie trzeba takich kodów wiele razy optymalizować w późniejszym czasie;

TekMast napisał(a)

Notacja węgierska to jest termin, który pierwszy raz w życiu spotkałem właśnie tutaj kilka postów wyżej, nie mam obowiązku znania tego i nie pisz, że to jest prawo bo chyba zbytnio się wczuwasz ;D

Gdybyś przeczytał jakikolwiek kurs czy książkę to wiedziałbyś co to notacja węgierska czy styl wielbłądzi; Ale tego nie zrobiłeś i teraz wymądrzasz się broniąc, ze to nie obowiązek; Gdybyś kiedykolwiek pracował nad projektem grupowym i koledzy z zespołu musieliby analizować Twoje nędznie sformatowane wypociny zostałbyś zlinczowany; Tutaj podając kod też dzielisz się nim, więc to samo dotknie Cię tutaj; Utrzymywanie zadbanego (formatowanego na bieżąco) kodu to bardzo wielka zaleta - dzięki temu oszczędza się dużo czasu - kiedyś to mam nadzieję zauważysz, ale będzie Ci ciężko pozbyć się starych nawyków;

TekMast napisał(a)

Nie każdy jest od razu zajebisty i popełnia błędy z różnych powodów np. niewiedzy więc wyluzuj i zwróć uwagę, że jedyne co pisałeś to mądrowanie się a zero pomocy.

Jeśli te słowa skierowane sa do mnie to zauważ, że poświęciłem czas na analizowanie tych kwiatków i podałem Ci gotowe rozwiązanie, które nie dość, że jest szybsze to pozwala na zużycie mniejszej ilości przestrzeni pamięci;

Jeżeli jednak tyczą się wypowiedzi @-123oho to zauważ, że słusznie wskazał Ci narzędzie, dzięki któremu można odnaleźć 99% błędów w kodzie pod warunkiem, że umie się z niego korzystać; Ty pewnie nie potrafisz i nawet nie wiesz gdzie takie narzędzie się znajduje, bo zapewne nie czytałeś ani jednego artykułu o podstawach debugowania aplikacji, a jest całkiem niezły dla początkujących: Debugowanie;

Podsumowując wypowiedź - najpierw zacznij naukę od czytania kursów / książek, a potem bierz się za kodzenie; Najpierw wypadałoby nauczyć się algorytmicznego myślenia, żeby kod układać sobie w głowie przed jego implementowaniem; Jest mnóstwo artykułów w sieci, książki też nie gryzą; Jest na tym forum dział Programowanie w języku Delphi jeśli chodzi o składnię, elementy języka oraz opisy procedur / funkcji i modułów; Jeśli mowa o standardach formatowania kodu przeczytaj artykuł Formatowanie kodu w Delphi; Masz potężną dawkę wiedzy dosłownie na wyciągnięcie ręki całkowicie za darmo, więc skorzystaj z niej i ćwicz zamiast pisać posty; Jeżeli teraz (pisząc bardzo krótkie programy) nie nauczysz się odnajdywania i naprawiania błędów oraz obsługi debugger'a to pisząc kilkuset liniowe (i więcej) kody na pewno nie poradzisz sobie z nimi i będziesz stałym klientem działu Newbie (a ten wątek się do tego działu nadaje) pisząc o rzeczach trywialnych; Nikt nie robi Ci tutaj na złość krytykując Twój kod i postawę - weź to pod uwagę i wyciąg wnioski na przyszłość;

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