Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Programm hängt sich auf...


drsnoop - Fr 23.01.04 16:39
Titel: Programm hängt sich auf...
habe ein probelm mit folgendem programm:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
procedure TForm1.Button1Click(Sender: TObject);
 var i, j, nummert, nummerk : integer;
     code : string;
     zeichen : char;

begin
 if (m_eingabe.text = ''or
    (tf_key.text = '')
     then application.messagebox('Bitte alle Eingaben machen.','Fehler',16)
     else
      begin
       code := '';
       for i := 1 to length(m_eingabe.text) do
        begin
         j := i;
         nummert := ord(m_eingabe.text[i]);
          while j > length(tf_key.text) do
           begin
            j := i - length(tf_key.text);
           end;
          nummerk := ord(tf_key.text[j]);
          zeichen := chr(nummert + nummerk);
          code := code + zeichen;
        end;
       m_ausgabe.text := code;
      end;
end;



m_eingabe und m_ausgabe sind memos, tf_key ist ein edit-feld...

es geht in dem programm darum, einen text zu codieren mit einem schlüsselwort. das schlüsselwort wird in tf_key eingetragen. dann werden jeweils das erste zeichen der beiden eingaben, und die ordnungsnummern davon zusammengezählt... wenn tf_key.text kürzer ist als m_eingabe, soll der schlüssel wieder von vorne anfangen, unzwar so lange, bis das ende des satzes, welcher in m_eingabe eingegeben wird, zuende ist. wenn ich jedoch auf button1 klicke, hängt sich das programm einfach auf... woran liegt das? bin mir eigentlich ziemlich sicher, dass ich den quältext richtig habe oder?

lange rede, kurzer sinn... wer kann mir dabei helfen? :roll:

danke schomal im vorraus... :D


drsnoop - Fr 23.01.04 20:48

*hervorschieb* :roll:


MaxiTB - Fr 23.01.04 21:01

Erstens mal macht man so eine Hervorschiebsache nicht - schähme dich mal ganz ordentlich. Wir, also vor allem ich, schauen eh hin und wieder das Forum durch, ob noch was unbeantwortet ist - wirst schon nicht übersehen :wink: .

Zweitens kann ich auf die schnelle einen Fehler orten - oder sagen wir so, eine Fehlerquelle:


Delphi-Quelltext
1:
 zeichen := chr(nummert + nummerk);                    


Schlecht, gaaanz schlecht *g*.

Erstens solltest du nur Zeichen im Bereich 0-255 hier rausbekommen (besser noch 32-127 ... ist weniger gefährlich, weil ASCII) ... alles was drüber ist ... *puh* Da wirds bei ANSI haglich, wie man so schön in Österreich sagt, weil das UNICODE-Zeichen sind die in MBCS-Zeichen von Delphi konvertiert werden. Wenn dir das jetzt nix sagt, laß es mich so sagen: Sehr schlecht, weil ein Zeichen auf einmal zwei werden können und ich hab keine Ahnung, ob nicht noch andere Effekte passieren oder das überhaupt immer geht !

Meine Empfehlung: Codierungsalgortihmus ändern ... z.B. so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
// Dein Code +
var
 lCode: integer;
// Dein Code statt code := code + zeichen;
 lCode:=nummert+nummerk;
 while lCode>127 do dec(lCode,127-32);
 code:=code+chr(lCode);


Jetzt bin ich mal fies und lasse dich grübbeln, was das genau tut - und wie der Decodierungsalgorithmus aussieht :P .

Kannst ja nochmals nachfragen, wenn du doch nicht draufkommst :D


Delete - Fr 23.01.04 22:11

Was verstehst du unter "aufhängen"? Kommt es in eine endlos Schleife oder reagiert es einfach nicht mehr? Sollte zweiteres der Fall sein, bau mein ein Application.Processmessages in die Schleife ein.


drsnoop - Do 29.01.04 13:41

sorry wegen dem *vorschieb*... *schäm* :oops:


@ Maxi:

1. darf eine variable mit einer zahl anfangen? ich dachte, das geht nicht...

2. wenn der am ende von 255 angekommen ist, dann fängt der doch wieder von vorne an in der ansi-tabelle...

3. was macht die funktion dec(x,y) ???


@ Luckie

es bleibt einfach stehen, nachedem ich den button drücke und reagiert auf keinerlei klicks oder tastenkombinationen mehr...


EDIT:

ach ja...

das selbe problem habe ich auch mit diesem programm:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
procedure TForm1.Button2Click(Sender: TObject);
var i, dezi : integer;
    ergebnis, buchstabe : string;
begin
 if (tf_dezi.text = '')
    then application.messagebox('Bitte Feld ausfüllen','Fehler',16)
    else
     for i := 1 to length(tf_dezi.text) do
      if (ord(tf_dezi.text[i]) < 48or
         (ord(tf_dezi.text[i]) > 57)
         then application.MessageBox('Bitte nur Zahlen ins Feld eingeben','Fehler',16)
         else
          begin
          buchstabe := '';
          dezi := strtoint(tf_dezi.text);
           while (dezi > 0do
            begin
             case (dezi mod 16of
               0 : buchstabe := '0';
               1 : buchstabe := '1';
               2 : buchstabe := '2';
               3 : buchstabe := '3';
               4 : buchstabe := '4';
               5 : buchstabe := '5';
               6 : buchstabe := '6';
               7 : buchstabe := '7';
               8 : buchstabe := '8';
               9 : buchstabe := '9';
              10 : buchstabe := 'A';
              11 : buchstabe := 'B';
              12 : buchstabe := 'C';
              13 : buchstabe := 'D';
              14 : buchstabe := 'E';
              15 : buchstabe := 'F';
             end//case
            ergebnis := ergebnis + buchstabe;
           end;
         tf_hexa.text := ergebnis;
      end;
end;


Delete - Do 29.01.04 14:29

Ja, bau doch mal in die Schleife ein Application.Processmessages ein. Du musst deinem Programm ja auch die Chance geben Nachrichten zu verarbeite.


teebee - Do 29.01.04 16:17

drsnoop hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
procedure TForm1.Button2Click(Sender: TObject);
var i, dezi : integer;
    ergebnis, buchstabe : string;
begin
 if (tf_dezi.text = '')
    then application.messagebox('Bitte Feld ausfüllen','Fehler',16)
    else
     for i := 1 to length(tf_dezi.text) do
      if (ord(tf_dezi.text[i]) < 48or
         (ord(tf_dezi.text[i]) > 57)
         then application.MessageBox('Bitte nur Zahlen ins Feld eingeben','Fehler',16)
         else
          begin
          buchstabe := '';
          dezi := strtoint(tf_dezi.text);
           while (dezi > 0do // hier fängt eine Endlosschleife an
            begin
             case (dezi mod 16of
               0 : buchstabe := '0';
               1 : buchstabe := '1';
               2 : buchstabe := '2';
               3 : buchstabe := '3';
               4 : buchstabe := '4';
               5 : buchstabe := '5';
               6 : buchstabe := '6';
               7 : buchstabe := '7';
               8 : buchstabe := '8';
               9 : buchstabe := '9';
              10 : buchstabe := 'A';
              11 : buchstabe := 'B';
              12 : buchstabe := 'C';
              13 : buchstabe := 'D';
              14 : buchstabe := 'E';
              15 : buchstabe := 'F';
             end//case
            ergebnis := ergebnis + buchstabe;
            // hier gehört eine neue Zuweisung an 'dezi' hin
           end;
         tf_hexa.text := ergebnis;
      end;
end;


Du hast eine Endlosschleife gebaut. Da du 'dezi' keinen Wert mehr zuweist, ist es immer >0 und Deine Schleife terminiert nicht.

Gruß, teebee


drsnoop - Do 29.01.04 16:21

hab es mal umgeändert und sieht jetzt so aus:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
procedure TForm1.Button2Click(Sender: TObject);
var i, dezi : integer;
    ergebnis, buchstabe : string;
begin
 if (tf_dezi.text = '')
    then application.messagebox('Bitte Feld ausfüllen','Fehler',16)
    else
     for i := 1 to length(tf_dezi.text) do
      if (ord(tf_dezi.text[i]) < 48or
         (ord(tf_dezi.text[i]) > 57)
         then application.MessageBox('Bitte nur Zahlen ins Feld eingeben','Fehler',16)
         else
          begin
          buchstabe := '';
          dezi := strtoint(tf_dezi.text);
           while (dezi > 0do
            begin
             case (dezi mod 16of
               0 : buchstabe := '0';
               1 : buchstabe := '1';
               2 : buchstabe := '2';
               3 : buchstabe := '3';
               4 : buchstabe := '4';
               5 : buchstabe := '5';
               6 : buchstabe := '6';
               7 : buchstabe := '7';
               8 : buchstabe := '8';
               9 : buchstabe := '9';
              10 : buchstabe := 'A';
              11 : buchstabe := 'B';
              12 : buchstabe := 'C';
              13 : buchstabe := 'D';
              14 : buchstabe := 'E';
              15 : buchstabe := 'F';
             end//case
            ergebnis := ergebnis + buchstabe;
            dezi := dezi mod 16;
           end;
         tf_hexa.text := ergebnis;
      end;
end;


löppt aber immernoch net.....

und wie baue ich application.processmessages ein?

gib mal ein beispiel büdde Luckie.... :D


teebee - Do 29.01.04 16:43
Titel: Re: Programm hängt sich auf...
Da ist auch wieder eine Endlosschleife drin, j wird nur einmal verkleinert, (an der Stelle ist i konstant), die While-Schleife terminiert nicht. Ich glaube, Du wolltestj := j - length(tf_key.text);
Warum setzst Du j immer auf i? Setze es zuerst auf 1, erhöhe es bei jedem Schritt um eins, und setze es wider auf 1, sobald es über das Ende des Keys hinauszeigt.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
begin 
       code := ''
       j := 1// hier schon j auf 1
       for i := 1 to length(m_eingabe.text) do 
        begin 
          nummert := ord(m_eingabe.text[i]); 
          nummerk := ord(tf_key.text[j]); 
          zeichen := chr(nummert + nummerk); // ist etwas holprig, siehe Posting von MaxiTB
          code := code + zeichen; 
          Inc(j); // j um eins erhöhen
          If j>Length(tf_key.text) Then j:= 1// und wieder auf 1 setzen, wenn zu groß
        end;


Gruß, teebee


drsnoop - Do 29.01.04 16:54

YEAH!!!


also das mit der codierung passt jetzt!!!


es lag an der schleife... vielen dank teebee!!! :D


aber was ist mit dem anderen programm?

warum stürzt es immernoch ab?


teebee - Do 29.01.04 17:00

Naja, schau Dir die While-Schleife von vorhin nochmal genauer an. Du machst jetztdezi := dezi mod 16Wenn da nicht zufällig 0 rauskommt, hängts wieder...
Vielleicht solltest im Case mal 'dezi Div 16' machen und untendezi := dezi - dezi Div 16;
Gruß, teebee


teebee - Do 29.01.04 17:22

Sorry, das wird immernoch nicht gehen...

Am einfachsten benutzst Du IntToHex....

Gruß, teebee


drsnoop - Do 29.01.04 17:24

meinst du so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
             case (dezi div 16of
               0 : buchstabe := '0';
               1 : buchstabe := '1';
               2 : buchstabe := '2';
               3 : buchstabe := '3';
               4 : buchstabe := '4';
               5 : buchstabe := '5';
               6 : buchstabe := '6';
               7 : buchstabe := '7';
               8 : buchstabe := '8';
               9 : buchstabe := '9';
              10 : buchstabe := 'A';
              11 : buchstabe := 'B';
              12 : buchstabe := 'C';
              13 : buchstabe := 'D';
              14 : buchstabe := 'E';
              15 : buchstabe := 'F';
             end//case
            ergebnis := ergebnis + buchstabe;
            dezi := dezi - dezi div 16;



das kann ich nicht machen, sonst ist der logarythmus für die umrechnung hin...



...und es stürtzt ab... :cry:


drsnoop - Do 29.01.04 17:25

teebee hat folgendes geschrieben:
Sorry, das wird immernoch nicht gehen...

Am einfachsten benutzst Du IntToHex....

Gruß, teebee



ich wollte den logarythmus aber selber mal versuchen weißt du? :D


teebee - Do 29.01.04 17:40

[Edit]Sorry, erstes Posting war totaler Mist...Nicht verwirren lassen!! Hoffe jetzt stimmt es besser...[/Edit]

Ok, wenn Du Dir den Algorithmus selbst herleiten willst, dann solltest Du das ganze vielleicht erst mal zu Fuß machen.
Du musst zuerst die Potenz von 16 herausfinden, die gerade kleiner ist als Deine Dezimalzahl. Das ist Dein Startwert.

Bsp:
Dezimal = 280
16^3 = 4096 -> größer as Dezimalzahl
16^2=256 -> gerade kleiner, Startwert

Jetzt ist Deine erste Hexziffer der ganzzahlige Teil einer Division Deiner Dezimalzahl durch 16^2, hier 1.
Die Dezimalzahl muss jetzt um 1*16^2 erniedrigt werden, es bleiben 24.
Im nächsten Durchlauf nimmst Du 16^1, bis 16^0, danach bist Du fertig.

Das ganze in eine Schleife zu packen, überlasse ich jetzt Dir,
Viel erfolg, teebee


drsnoop - Do 29.01.04 19:02

*schlaubergermodus an*

die bestimmte abfolge zum umwandel einer hexadezimalzahl ist der logarythmus...

der code selbst heißt algorythmus...

*schlaubergermodus aus* :D


und den logarythmus habe ich ja:

nehmen wir zum beispiel die zahl 2989.


2989 mod 16 ergibt 186 rest 13; 13 = D
186 mod 16 ergibt 11 rest 10; 10 = A
11 mod 16 ergibt 0 rest 11; 11 = B

hex = BAD


so find ich es einfacher :D


und genau so habe ich es ja eigentlich auch gemacht... ich weiß aber nicht, wo meine fehler liegt.... :cry:


EDIT:


aaaaaalso...

habe das programm nun soweit, dass es mir die zahl umrechnet, die ich eingebe... allerdings... sobald das programm an buchstaben drankommt, vervielfacht es sie...

wenn ich zum beispiel 15 eingebe, spuckt der mir "FF" aus anstatt "F".

und bei 2989 kommt "BADBADBADBAD" raus...

so sieht dat momentan aus:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
procedure TForm1.Button2Click(Sender: TObject);
var i, dezi : integer;
    ergebnis, buchstabe : string;
begin
 if (tf_dezi.text = '')
    then application.messagebox('Bitte Feld ausfüllen','Fehler',16)
    else
     for i := 1 to length(tf_dezi.text) do
      if (ord(tf_dezi.text[i]) < 48or
         (ord(tf_dezi.text[i]) > 57)
         then application.MessageBox('Bitte nur Zahlen ins Feld eingeben','Fehler',16)
         else
          begin
          buchstabe := '';
          dezi := strtoint(tf_dezi.text);
           while dezi > 0 do
            begin
             case (dezi mod 16of
               0 : buchstabe := '0';
               1 : buchstabe := '1';
               2 : buchstabe := '2';
               3 : buchstabe := '3';
               4 : buchstabe := '4';
               5 : buchstabe := '5';
               6 : buchstabe := '6';
               7 : buchstabe := '7';
               8 : buchstabe := '8';
               9 : buchstabe := '9';
              10 : buchstabe := 'A';
              11 : buchstabe := 'B';
              12 : buchstabe := 'C';
              13 : buchstabe := 'D';
              14 : buchstabe := 'E';
              15 : buchstabe := 'F';
             end//case
            ergebnis := buchstabe + ergebnis;
            dezi := dezi div 16;
           end//while
          end;
         tf_hexa.text := ergebnis;
end;


teebee - Do 29.01.04 22:56

drsnoop hat folgendes geschrieben:
*schlaubergermodus an*

die bestimmte abfolge zum umwandel einer hexadezimalzahl ist der logarythmus...

der code selbst heißt algorythmus...

*schlaubergermodus aus* :D
Aha... :?:
Also: 'logarythmus' gibt es nicht, es heisst 'logarithmus' und der L. einer Zahl b zu einer Basis a ist derjenige Exponent x, mit dem man die Basis a potenzieren muss, um b zu erhalten. Steht in jedem Mathebuch... :wink:
Mit der Umwandlung von Zahlen in anderen Zahlensysteme hat das nix zu tun...
Ein Algorithmus ist eine eindeutige Vorschrift zur Lösung einer Aufgabe, ob in einer Programmiersprache oder sonstwie formuliert ist egal.

Jetzt zu Deinem Problem:
Du durchläufst Deine Hex-Schleife ja für jede Stelle Deiner Dezimalzahl einzeln, 4 Stellen (2989) -> 4*BAD, 2 Stellen (15) -> 2*F.

Trenne einfach die Überprüfung auf Zahlwenwerte von der eigentlichen Umrechnung, dann klappt's.

Gruß, teebee