Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Komme mit Val() nicht klar


theevilworm - So 25.10.09 17:03
Titel: Komme mit Val() nicht klar
Hallo,

der Titel sagt alles. Ich weiß nicht recht, wie ich Val() benutzen soll.
Ich habe hier zwei Editfelder, die beide nur Zahlen akzeptieren sollen, jedoch keine Null als einzelnes, Nullen in Zahlen sind erlaubt (10, 20, 103: Ja. 0: Nein). Dazu habe ich durch Google dieses gute Tutorial hier gefunden:
http://www.delphi-treff.de/tutorials/programmierkonzepte/fehlermeldungen/page/8/

Ich habe den Abschnitt, bei dem man Buchstabeneingaben komplett abfangen kann, befolgt und es klappt super. Leider ist ja nun auch noch das Einfügen von Buchstaben aus der Zwischenablage möglich. Dazu wollte ich die Funktion Val() aus dem Tutorial benutzen.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  divisor: Integer;
  ErrorCode: Integer;
begin
  Val(Edit1.Text, divisor, ErrorCode);
  if ErrorCode = 0 then // kein Fehler ==> gültiger Wert
...


Das habe ich versucht in mein Beispiel zu übertragen, und wie unerwartet: es funktioniert nicht.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TForm1.Button6Click(Sender: TObject);
var ErrorCode:Integer;
begin
Val(Edit1.Text, edit2.text, ErrorCode);

end;


"Inkompatible Typen"...
Kann mir jemand bitte hlefen? :P

Weiterhin habe ich probiert, die Null abzufangen:


Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.Button6Click(Sender: TObject);

begin
If StrToInt(edit1.text) or StrToInt(edit2.text)=0 then
  showmessage ('Bitte Zahl größer Null eingeben!')


Auch dies funktioniert nur, wenn ich in beide Felder eine 0 eingebe, und auch nur eine einzelne Null. 000 geht zum beispiel durch.
Wie kann ich das abfangen?


Marc. - So 25.10.09 17:08

Vergleich doch einfach mal den zweiten Parameter, den du übergeben hast, mit dem aus dem Beispiel. ;)


theevilworm - So 25.10.09 17:12

Naja, mein Edit2.Text ist ein String, und divisoe im Beispiel ist ein Integer.
Aber genau das will ich ja mit Val() rausfinden, ob Edit2.Text ein Integer sein kann. Ich versteh nichtmal, warum der Autor des Tutorials divisor prüfen lässt.


Marc. - So 25.10.09 17:28

user profile icontheevilworm hat folgendes geschrieben Zum zitierten Posting springen:
Naja, mein Edit2.Text ist ein String, und divisoe im Beispiel ist ein Integer.
Aber genau das will ich ja mit Val() rausfinden, ob Edit2.Text ein Integer sein kann. Ich versteh nichtmal, warum der Autor des Tutorials divisor prüfen lässt.

Val markieren und F1 drücken. Die DOH hilft dir da sicher weiter. :idea:


theevilworm - So 25.10.09 17:36

Hat mir nicht wirklich geholfen :(
Wie sollte denn der Code aussehen?
Das klappt auch nicht:

Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.Button6Click(Sender: TObject);
var ErrorCode, ValInteger:Integer;
begin
Val(Edit1.Text, edit2.text, valinteger, ErrorCode);
end;


Stundenplan - So 25.10.09 17:58

Das hat zwar weniger mit Val() zu tun, aber...vielleicht hilfts dir ja trotzdem:
Würde es nicht auch gehen, wenn du die Quersumme EINMALIG aus dem Wert berechnest und kuckst, ob sie > 0 ist? :wink:

Also nicht:
10273 -> 13 -> 4
sondern
10273 -> 13 STOP


theevilworm - So 25.10.09 18:22

Hat Val() irgendwas mit der Quersumme zu tun? Das wusste ich gar nicht, ich hab das nur in dem Tutorial aufgeschnappt.
Jetzt bin ich total verwirrt. Kann irgendjemand bitte einen funktionieren Code posten, der das mit Val() überprüft (und evt. auch noch eine Null-Eingabe abfängt)?


Marc. - So 25.10.09 20:21

user profile icontheevilworm hat folgendes geschrieben Zum zitierten Posting springen:
Hat Val() irgendwas mit der Quersumme zu tun?

Nein. Die Funktion Val() konvertiert einen String S (erster Param) in das Integer- oder Gleitkomma-Format (abhäng. von V!) und weißt dieses Ergebnis einer Variablen V (zweiter Param) zu. Ist die Konvertierung ungültig, i.e. lässt sich der String nicht in eine Zahl umwandeln, so wird der Index des ersten ungültigen Zeichens der Variable C (dritter Param) übergeben.

Alternativ bieten sich für dein Vorhaben auch die Funktionen TryStrToFloat() und StrToFloatDef() an. Mehr dazu in der DOH. ;)


theevilworm - So 25.10.09 20:41

Ich glaube ich bin einfach zu doof... Was mache ich hier falsch:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TForm1.Button6Click(Sender: TObject);
var ErrorCode, ErrorCode2, ValInteger:Integer;
begin
val (edit1.text, valinteger, errorcode);
val (edit2.text, valinteger, errorcode2);
If not ((errorcode=0or (errorcode2=0)) then
  begin
  showmessage ('Hier kann man nur Zahlen eingeben, Dulli');
  end;
end;


Wenn ich in beiden Editfeldern Buchstaben eingebe, kriege ich die Message. Wenn in einem von beidem nur Zahlen sind, nicht. Dabei habe ich doch extra OR verwendet.


elundril - So 25.10.09 21:22

weil du ein and statt einem or verwenden musst. ;) wegen dem not.

weil not (a or b) ist das gleiche wie (not a) and (not b). und da muss ja beides false sein damit es insgesamt als wahr gewertet wird. ;) deswegen wenn du not (a and b) schreibst, wird das als (not a) or (not b) gewertet.

andere methode wäre einfach das not wegzulasse und auf ungleichheiten zu überprüfen. ;)

lg elundril


Marc. - So 25.10.09 21:24

user profile icontheevilworm hat folgendes geschrieben Zum zitierten Posting springen:
Wenn ich in beiden Editfeldern Buchstaben eingebe, kriege ich die Message. Wenn in einem von beidem nur Zahlen sind, nicht. Dabei habe ich doch extra OR verwendet.

Boolsche Algebra [http://de.wikipedia.org/wiki/Boolesche_Algebra]:
Variante A:

Delphi-Quelltext
1:
if (errorcode <> 0or (errorcode2 <> 0then                    

Variante B:

Delphi-Quelltext
1:
if not ((errorcode = 0and (errorcode2 = 0)) then                    


der organist - Mo 26.10.09 00:20

der Ausdruck sagt dir, dass es wahr ist, wenn nicht einer von beiden wahr ist. Sprich, wenn beide falsch sind....


BenBE - Di 27.10.09 10:44

user profile iconMarc. hat folgendes geschrieben Zum zitierten Posting springen:
user profile icontheevilworm hat folgendes geschrieben Zum zitierten Posting springen:
Wenn ich in beiden Editfeldern Buchstaben eingebe, kriege ich die Message. Wenn in einem von beidem nur Zahlen sind, nicht. Dabei habe ich doch extra OR verwendet.

Boolsche Algebra [http://de.wikipedia.org/wiki/Boolesche_Algebra]:


Variante C:

Delphi-Quelltext
1:
if (errorcode or errorcode2) <> 0 then                    


Der Vollständigkeit halber (Ist semantisch aber was anderes als Varianten A und B).


JayEff - Di 27.10.09 10:44

Wenn du nur prüfen willst, ob in einem Feld eine Zahl steht (Also ein Integer-Wert in Form eines Strings), dann reicht doch TryStrToInt zu nutzen: if TryStrToInt(myString, myInt) then {klappt, in myInt steht jetzt die Zahl} else {klappt nicht}
Das findet man aber auch, wenn man die DOH zu TryStrToInt fragt, wie's schonmal empfohlen wurde ;)

user profile icontheevilworm hat folgendes geschrieben Zum zitierten Posting springen:
Weiterhin habe ich probiert, die Null abzufangen:


Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.Button6Click(Sender: TObject);

begin
If StrToInt(edit1.text) or StrToInt(edit2.text)=0 then
  showmessage ('Bitte Zahl größer Null eingeben!')


Auch dies funktioniert nur, wenn ich in beide Felder eine 0 eingebe, und auch nur eine einzelne Null. 000 geht zum beispiel durch.
Wie kann ich das abfangen?

:shock: Da kommt keine Fehlermeldung? Erstaunlich! Du behandelst da einen Integer als Ja/Nein-Wert. Deine Abfrage lässt sich wie folgt umformulieren (und wenn man das tut, merkt man, dass das keinen Sinn macht!):

Delphi-Quelltext
1:
2:
3:
if StrToInt(edit1.text) then //äh, wie bitte?
  if StrToInt(edit2.text)=0 then
    showmessage('asd');

Die Syntax für Abfragen mit Boolschen Operatoren (and, or etc) ist immer:  if Aussage_A or Aussage_B ... wobei die Aussagen in sich eine vollwertige "Abfrage" sein müssen, wie z.B. (StrToInt(edit1.text) = 0). Hier sind auch die Klammern unerlässlich. Richtig heißt es also: if (StrToInt(edit1.text) = 0or (StrToInt(edit2.text) = 0then {fehler}