Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Warum verschluckt er eine Zahl? ,Schleifen und Typumwandlung


daywalker0086 - Di 28.10.08 22:47
Titel: Warum verschluckt er eine Zahl? ,Schleifen und Typumwandlung
Hallo an euch,
habe mal wieder eine Frage, habe folgenden kleinen Code:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
 Daten2:= SerialPortNG1.ReadNextClusterAsString() ;
        hex:= strtohex(Daten2);
        stringlaenge:=length(Daten2);

        setlength(Daten,6);
        abschnitt:= 0;
        for D:=0 to high(Daten) do
        begin
        Daten[D]:= copy(hex, abschnitt, abschnitt+1) ;
        abschnitt:= abschnitt+1  ;
        Memo1.Lines.add(Daten[D]);

        end;


Mein String den ich auf den Port schicke lautet 4D 5A 01 41 00 E9 .
Wenn dann mein Memo gefüllt wird steht dann D5A da. Also fehlt die 4, warum verschluckt er die?
Weiterhin soll eigentlich in jedes Feld des Arrays ein hex Wert, also zB. 4D stehen,
aber da steht dann eben im Memo das:
D5A
5A01
A0141
014100
Da wird wohl was ander Schleife fallsch sein, da finde ich aber auch nicht den Fehler.
Könnt ihr mir da helfen?
Eigentlich mach ich das um die Daten in dezimal umzuwandeln und dann zusammen zu rechnen, nur damit ihr wisst für was das ist.


Dunkel - Di 28.10.08 23:06

Hallo!

Zuerstmal, aus Deinem Codeschnipsel ist nicht ersichtlich, wo die führende 4 abgeblieben ist.
Zweitens: mach Dich nochmal über die Syntax von Copy schlau. Der dritte Parameter gibt nämlich nicht an, bis wohin kopiert werden soll, dort wird die Anzahl der zu kopierenden Zeichen angegeben!


daywalker0086 - Di 28.10.08 23:25

Danke für deinen Hinweis, habe es jetzt abgeändert:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
 Daten2:= SerialPortNG1.ReadNextClusterAsString() ;
        hex:= strtohex(Daten2);
        stringlaenge:=length(Daten2);

        setlength(Daten,6);
        abschnitt:= 0;
        for D:=0 to high(Daten) do
        begin
        Daten[D]:= copy(hex, abschnitt, 2) ;
        abschnitt:= abschnitt+1  ;
        Memo1.Lines.add(Daten[D]);

        end;

aber die 4 von 4D5A014100E9 wird immernoch verschluckt.
Im Memo steht jetzt
D5
5A
A0
01
Hier nochmal die Variablendeclaration:

Delphi-Quelltext
1:
2:
3:
 hex, bestaetigung, line: string;
  Daten: array of string;
  D: integer;


alzaimar - Di 28.10.08 23:43

abschnitt fängt bei 1 an und muss um 2 erhöht werden.


daywalker0086 - Di 28.10.08 23:47

Jezt hab ichs so und er fängt bei 4 an:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
setlength(Daten,6);
        abschnitt:= 0;
        for D:=1 to high(Daten) do
        begin
        Daten[D]:= copy(hex, abschnitt, 2) ;
        abschnitt:= abschnitt+1  ;
        Memo1.Lines.add(Daten[D]);


Aber ein Problem ist noch, jetzt steht in der Memobox:
4D
D5
5A
A0
also er macht dann immer das zweite Zeichen doppelt, wie muss ichs schreiben damit es passt?


jasocul - Mi 29.10.08 09:19

Da wirst du wohl eine While-Schleife benutzen müssen. Eine For-Schleife macht immer nur einen Schritt und du musst zwei Schritte machen.


Jerk - Mi 29.10.08 09:27


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  setlength(Daten,6);
  for D := 0 to high(Daten) do
  begin
    Daten[D]:= copy(hex, D * 2 , 2) ;
    Memo1.Lines.add(Daten[D]);
  end;


Ich Denke das sollte gehen.


jasocul - Mi 29.10.08 10:43

Nicht ganz:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  setlength(Daten,6);
  for D := 0 to ((high(Daten) div 2) -1do // Man muss nur noch die Hälfte durchlaufen
  begin
    Daten[D]:= copy(hex, (D * 2) + 1 , 2); // +1 ist noch notwendig.
    Memo1.Lines.add(Daten[D]);
  end;


daywalker0086 - Mi 29.10.08 14:17

Danke Jasocul, es funktioniert, kannst du mir mal erklären was die Zeile bringt
for D := 0 to ((high(Daten) div 2) -1do // Man muss nur noch die Hälfte durchlaufen
also was es bringt, dass die Schleife nur noch halb soviel durchläuft?


jasocul - Mi 29.10.08 14:26

Im Copy-Befehl startest du bei den Zeichen 1, 3 und 5, um jeweils zwei Zeichen zu lesen.
Du hast also genau 3 Zugriffe auf den String. Dein String ist aber 6 Zeichen lang. Wenn du das nicht veränderst, greifst du auf die Zeichen 1, 3, 5, 7, 9 und 11 zu. 7 bis 11 gibt es aber gar nicht. Deswegen muss du die Schleifendurchläufe ebenfalls reduzieren.

Dem Copy-Befehl ist es zwar egal, wenn du versuchst über das Ende hinaus zu lesen, aber es gibt andere Fälle, wo das zu kompletten Programmabstürzen führen kann. Deswegen lieber gleich den richtigen Stil angewöhnen. Außerdem sparst du Rechenzeit. Bei dieser kleinen Schleife sicher uninteressant, aber bei umfangreicheren Schleifen sicher nicht.

Ich hoffe, dass das einigermaßen verständlich war.


daywalker0086 - Mi 29.10.08 16:13

Da hab ich gleich noch ne frage, die 6 Stellen sind nur willkürlich angegeben, es kommt auch vor, dass ich nen String mit 36 Stellen hab.
Wie muss ich die Arraygröße angeben, damit er mir die dynamisch macht, bzw. ich die nicht vorher festlege? Einfach die Größenangabe weg lassen?


daywalker0086 - Mi 29.10.08 19:28

wie bekomme ich denn von dem Hexwert den Dezimalwert?
Mit integerdaten:= ord(Daten[0])
funktioniert es nicht, kommt immer inkompatible Typen
integerdaten ist integer


Marc. - Mi 29.10.08 19:42

Ord erwartet ein Zeichen oder einen anderen ordinalen / aufzählbaren Typ, du übergibst aber einen String an die Funktion. :zwinker:

Es müsste also in etwa so lauten:

Delphi-Quelltext
1:
integerDaten := Ord(Daten[0][x]);                    


daywalker0086 - Mi 29.10.08 21:43

hm... jetzt steh ich aufm Schlauch


Marc. - Sa 01.11.08 01:29

user profile icondaywalker0086 hat folgendes geschrieben Zum zitierten Posting springen:
wie bekomme ich denn von dem Hexwert den Dezimalwert?

Die Funktion Val sollte Dir weiterhelfen:

Delphi-Quelltext
1:
Val('$'+Daten[x], integerDaten, Code);                    

Weitere Erklärungen dazu findest Du in der DOH. ;)
Alternativ gibt es auch einiges dazu im Forum, unter anderem hier [http://www.delphi-forum.de/viewtopic.php?p=245149#245149].