Entwickler-Ecke

Sonstiges (Delphi) - [Erledigt!] String nach Zeichen überprüfen


T.Peters - Do 22.01.04 15:25
Titel: [Erledigt!] String nach Zeichen überprüfen
Hi Leute,

ich hätte da mal ne Frage.
Ich möchte einen String einlesen. Danach soll der String überprüft werden und abgefragt werden, ob in ihm ungültige Zeichen sind. Wenn ja, dann soll eine Fehlermeldung erscheinen.
Die Abfrage darf nicht glich bei der Eingabe geschehen, sondern danach, weil es auf einen RadiButton ankommt, welche Zeichen in dem String sein dürfen.

Um es Euch etwas verständlicher zu machen: Es sollen hierbei nur Römische Zeichen eingegeben werden dürfen (IVXLCDM).

Danke im Vorraus
Gruß Torsten


matze - Do 22.01.04 15:28

also mit dem befehl pos kannst du testen, ob ein buchstabe in eine string vorkommt.

Delphi-Quelltext
1:
2:
     if pos ('e',edit1.text) > 0 then
        showmessage ('es ist ein e drin !');

pos gibt nämlich die position des zeichens zurück.
probier damit mal rum, ich denké mal, dass dir das helfen wird...


T.Peters - Do 22.01.04 15:32

OK könnte man verwenden.
Allerdings wird die Abfrage dann ziemlich lang, weil ich brauche das ganze ja für ABEFGHJKNOP....!
Kann man die Abfragen irgendwie koppeln und wird GROß- und kleinschreibung unterschieden?

PS Thx für deine schnelle Hilfe


MaxiTB - Do 22.01.04 15:32


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function IsLegal(Value: string; Legals: string): boolean;
var
 lIndex: integer;
 lPos: integer;
begin
 Result:=true;
 for lIndex:=1 to Length(Legals) do
 begin
  lPos:=Pos(Legals[lndex],Value);
  if lPos>-1 then begin Result:=false; end;
 end;
end;


Value ist der string, den du überprüfen willst, Legals enthält die gültigen Zeichen.


Chatfix - Do 22.01.04 15:34

Groß und klein wird unterschieden.
Mit UpperCase bzw UpCase könnte man das aber umgehen...


matze - Do 22.01.04 16:09

ich wollte auch nur einen denkanstoss geben !


T.Peters - Do 22.01.04 18:21

@Mäxchen
Danke, funktioniert wunderbar. Da ich diese Abfrage 4 Mal machen muß und jedsmal andere Zeichen gültig sind, bietet sich deine Lösung sehr an. Thx nochmal...

@matze
Danke, das hast du geschafft

@Chatfix
ich benutze dafür AnsiUpperCase();

Danke für die schnelle Hilfe
Gruß Torsten


Delete - Do 22.01.04 18:34

Siehste, das ist doch mal eine Antwort. Der Mann ist nicht sauer, wenn man ihm "nur" einen Denkanstoß gibt. :)

@Torsten: Wenn du willst, kannst du den Titel deines allerersten Beitrags ja noch bearbeiten und ein "[Erledigt]" anhängen, also:
Zitat:
String nach Zeichen überprüfen [Erledigt]

Dann wissen alle, dass du eine Lösung hast, und wer das gleiche Problem hat, weiß, dass er sie (die Lösung) hier findet. ;)

Gruß.


T.Peters - Do 22.01.04 19:12

hehe Mathias

Wiso sollte ich sauer sein. Das ganze Forum baut auf Kulanz auf und jeder der Antwortet will doch nur mein Bestes und das des Forums.

Ich werde später das Erledigt anhängen, da ich mir mittlerweile doch nicht mehr so sicher bin, das alles richtig ist.
Meine Antwort war ein wenig zu voreilig.
Wenn ich den Fehler finde un der in dem Code ist, werde ich natürlich die Lösung posten.

Gruß Torsten


T.Peters - Do 22.01.04 20:20

Also wenn ich das richtig verstanden habe, dann liefert Pos, wenn es den String nicht findet 0 zurück. Desshalb kann man nicht nach >-1 fragen; Weil die Funktion ja nur False zurückliefern soll, wenn eines der Zeichen gefunden werden.

Und die Legals sind bei mir jetzt die nicht legalen :D.

Dh: Wenn einer der Zeichen(nicht Gültige Zeichen) in Wert vorhanden ist gebe ein False zurück und showMessage();.

Das funktioniert auch soweit, bis ich dafür Zahlen benutze. Hier mal das Beispiel:

Habe die Variablen mal nach meinen Vorstellungen umbenannt


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function TForm1.Gueltigkeit(Wert: string; nErlaubt: string): boolean;
var
 iFor, iPos: integer;
begin
 Result:=true;
 for iFor:=1 to Length(nErlaubt) do
 begin
  iPos:= Pos(nErlaubt[iFor],Wert);
  if iPos>0 then begin Result:=false; end;
  Erg.Lines.Add('iPos ' + IntToStr(iPos));
 end;
end;


Der Aufruf lautet:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
begin
        nErl:= 'ABCDEFILMVX';
        Edt_Wert.text:= AnsiUpperCase(Edt_Wert.text);
        if (Gueltigkeit(Edt_Wert.text, nErl)= false)
          then
            begin
               Anweisungen;
            end
            else showmessage('keine gültige Eingabe');
      end;


Ich hoffe, das ich nix vergessen habe.
Also wenn ich nun als Wert eine 12 eingebe, sollte normalerweise alles funktionieren, aber es passiert anders rum. zahlen gehen nicht, aber die Buchstaben.

Währe nett wenn sich das nochmal einer anschauen kann.
Werde es mir dann morgen mal anschauen, also falls noch Fragen sind, kann ich die erst Morgen beantworten.

Thx & Gruß
Torsten

Moderiert von user profile iconMotzi: Code- durch Delphi-Tags ersetzt


MaxiTB - Do 22.01.04 20:27

Ups - kann sein, daß ich mich hier irre aber Pos liefert auf jedenfall die erste Position des Auftretens im String ab (pascal typisch) 1.

Es kann also durchaus sein, daß der Fehlerfall 0 ist ... passiert einen C-Veteranen öfters, daß er den String-1-Spezialfall durcheinanderbringt.

Aber einen kleinen Bug hast trotzdem, weil du die Logik doppelt umgedreht hast:


Delphi-Quelltext
1:
  if iPos<=0 then begin Result:=false; exit; end;                    


Result:=false wenn ungültig.
iPos liefert <=0 wenn das Zeichen nicht gefunden, daher ungültig.

Und dann noch das exit vergessen ... das wars schon.

Klar :wink: ?


T.Peters - Fr 23.01.04 20:44

OK Thx Mäxchen, ich bin momentan viel unterwegs, werde aber spätestens Sonntag sagen, was drus geworden ist. Bis dahin, frohes Wochenende und hoch die Tassen.

LG Torsten

PS: Ja das mit den Sprachen durcheinander bringen kenne ich, aber in der Delphi Hilfe steht das, wenn der/das Teilstring/Zeichen nicht gefunden wird, dann wird NULL zurückgegeben.


MSCH - Fr 23.01.04 21:08

komische krise krieg. Soviel Code für ein simples problem.
Ein Edit-Feld hat eine OnKey...() Methode. Einfach abfragen, ob die grad gedrückte Taste, innerhalb eines Wertebereiches liegt, wenn ja, --> inherited ansonsten key:=''.

Beispiel:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TEdit.nummerKeyPress(Sender: TObject; var Key: Char);
const
  KeysAllowed: Set of Char =['A','B','C'];
begin
  if not(Key in KeysAllowed) then Key:=#0;
  inherited;
end;


grez
msch


MaxiTB - Fr 23.01.04 21:13

::msch

Er hat aber explizit geschrieben, er will den Check erstens erst später machen und zweitens mit verschiedenen Sets :wink:


MSCH - Fr 23.01.04 21:19

wo liegt das Problem, wenn man statt einem, verschiedene Sets von Zeichen definiert die erlaubt sind und diese dann in der OnKeyXXX() Methode abfragt?
grez
msch


matze - Sa 24.01.04 11:55

aber man kann den code ja abwnadeln und dann später mal die zeichen des strings zeichen für zeichen durchgehen und schauen, ob die in dem set enthalten sind.


T.Peters - So 25.01.04 14:42

Also ich weiß ja nicht.
Erst mal was ist ein Set?
Zweitens: Ich habe soeine Key-Abfrage schon eingebaut, aber was du mit OnKeyXXX() meinst, versteh ich nicht ganz. kurze Erklärung: Ein EditFeld, vier RadioButtons, Es kommt drauf an, welcher Button aktiviert ist, weil damit definiert wird welche Zeichen erlaubt sind. Außerdem wird es meistens so gemacht, das der RadioButton, der die Zahl definiert, erst nach der Zahleingabe getätigt wird.
Nun meine Frage: Wie soll es gehen, etwas nach Gültigkeit abzufragen, wenn nicht definiert ist, was gültig ist?

Jetzt bin ich mal gespannt... :D

Gruß Torsten


MaxiTB - So 25.01.04 14:48

Antwort:
Geht gar nicht, weil du durchs umschalten ungültige Strings haben könntest; und wenn du die immer Löschen würdest, wäre das sehr, sehr benutzerunfreundlich - ist schon okay - hast es schon richtig angedacht.

On the fly Benutzereingaben zu zensieren ist selten eine gute Idee; ist zwar meistens die bequemere Art zu programmieren, aber damit macht man sich nicht viele Freund bei den Usern ...

Set sind eine Spezialität von Delphi ... bei einer solchen Menge von Zeichen würde ich aber trotzdem die Stringvariante verwenden (persönlich), weil so ein Set mir persönlich zuviel Tipparbeit ist und strings einfach universaler und bequemer zum Handieren sind - besonders wenn man später noch dies und das ändern will.


T.Peters - So 25.01.04 19:56

Also ich habe jetzt noch ein paar Fehler ausgebügelt, aber dies ist die End-Lösung:

Als erstes werden über eine KeyPress Funktion die erlaubten Zeichen ins EditFeld eingetragen.
Danach wird über die RadioButtons der Typ und somit die restichen unerlauben Zeichen definiert (gespeichert in var nErlaubt)

Abfrage des RB`s; nicht erlaubte Zahlen deklarieren; String in Großbuchstaben umwandeln; abfragen ob das Ergebnis der Gültigkeitsabfrage True or False ist und ausführen der entsprechenden Anweisungen.

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
if RadioButton1.Checked = true
    then
      begin
        nErl:= 'ILMVX';
        Edt_Wert.text:= AnsiUpperCase(Edt_Wert.text);
        if (Gueltigkeit(Edt_Wert.text, nerl)= True)
          then
            begin
              Anweisungen
            end
            else showmessage('keine gültige Eingabe');
      end;



Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
function TForm1.Gueltigkeit(Wert: string; nErlaubt: string): boolean;
var
 iFor, iPos: integer;
begin
 Result:=true;
 for iFor:=1 to Length(nErlaubt) do
 begin
  iPos:= Pos(nErlaubt[iFor],Wert);
  if iPos>0 then begin Result:=false; exit; end;
 end;
end;


Durch Pos() wird abgefragt, ob "Wert" das Zeichen, welches in "nErlaubt[iFor]" gespeichert ist, enthällt. Ist das Zeichen vorhanden, wird der Indexwert des ersten Zeichens zurückgegeben (Das Zeichen kann ja auch öffters vorkommen). Wird das Zeichen nicht gefunden, so gibt Pos() eine NULL zurück. Daher muß die Abfrage iPos>0 heißen.

Danke an alle, bis zum nächsten Mal

Gruß Torsten