AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?

Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?

Ein Thema von Kenshin4455 · begonnen am 28. Nov 2007 · letzter Beitrag vom 7. Feb 2011
Antwort Antwort
Seite 2 von 3     12 3   
SvenLittkowski

Registriert seit: 18. Dez 2004
98 Beiträge
 
#1

AW: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?

  Alt 7. Feb 2011, 05:29
Und wie kann man testen ob ein String eine Zahl darstellt, wenn jene Zahlen auch negativ (mit vorangestelltem Minus) sein können und vom Typ Integer oder Real sein können (also mit Kommastellen, wobei das Komma je nach Land durch ein Komma oder einen Punkt dargestellt sein kann)? Gleichzeitig will ich aber Strings wie die nachfolgenden "Un"-Zahlen ausschließen:
- "12-3"
- "123-"
- "123."
- "1.2.3"
- "1-2-3"
- "-.-"

Bei meinem Problem kann ich mit Schleifen arbeiten. Nur der Algorithmus fällt mir nicht ein.

Geändert von SvenLittkowski ( 7. Feb 2011 um 05:32 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.374 Beiträge
 
Delphi 12 Athens
 
#2

AW: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?

  Alt 7. Feb 2011, 09:57
Das Einfachste: Delphi-Referenz durchsuchenVal, Delphi-Referenz durchsuchenTryStrToInt, Delphi-Referenz durchsuchenTryStrToFloat, ...

Delphi-Referenz durchsuchenDecimalSeparator

Ansonsten einfach alles nacheinander prüfen und schauen, ob was Richtiges/Falsches drin vorkommt.
Delphi-Quellcode:
Result := False;
i := 1;
if (i <= Length(S)) and (S[i] in ['+', '-']) then
  Inc(i);
if (i > Length(S)) or not (S[i] in ['0'..'9']) then
  Exit;
while (i <= Length(S)) and (S[i] in ['0'..'9']) do
  Inc(i);
if (i <= Length(S)) and (S[i] = DecimalSeparator) then
begin
  Inc(i);
  if (i > Length(S)) or not (S[i] in ['0'..'9']) then
    Exit;
  while (i <= Length(S)) and (S[i] in ['0'..'9']) do
    Inc(i);
end;
Result := i > Length(S);
Das läßt sich natürlich noch ein bissl hübscher zusammenfassen.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 7. Feb 2011 um 10:02 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.659 Beiträge
 
Delphi 12 Athens
 
#3

AW: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?

  Alt 7. Feb 2011, 10:02
http://www.delphipraxis.net/158131-t...tige-real.html
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Deep-Sea
Deep-Sea

Registriert seit: 17. Jan 2007
907 Beiträge
 
Delphi XE2 Professional
 
#4

AW: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?

  Alt 7. Feb 2011, 10:02
@himitsu & alle anderen:
Das Post von SvenLittkowski wurde von ihm auch in einem eigenen Thread gepostet, der unter dem Namen Test ob gültige REAL zu finden ist

PS: Ach DeddyH ...... :p
Chris
Die Erfahrung ist ein strenger Schulmeister: Sie prüft uns, bevor sie uns lehrt.
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#5

Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?

  Alt 29. Nov 2007, 08:39
Zitat von LoCrux:
Und & Vergleichsoperationen:
Im besten Fall n=2 , im schlimmsten fall n=Length(s)*2 Operationen.
Noch etwas besser wäre es imho, wenn man gleich mehrere Byte testet. Immerhin passt in ein Register auf den meisten CPUs schon mal mind. 32 Bit, entsprechend kann man auch eine Maske dieser Größe wählen und 4 Byte aufeinmal testen. Ändert natürlich nichts an der Asymptotischen Laufzeit, aber da käme ja auch das i-fache StrToInt in Frage.
  Mit Zitat antworten Zitat
Kenshin4455

Registriert seit: 28. Nov 2007
3 Beiträge
 
#6

Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?

  Alt 29. Nov 2007, 11:31
Danke erstmal für die Vorschläge!!

Prinzipell gings nur darum das ich nich alles durchgehen wollt. Grund ist das die Daten für die Verarbeitung korrekt vorliegen müssen sprich eine durchgängige Zahl ohne Buchstaben Sonderzeichen etc. dazwischen. Ich könnte den Fehlerabfanng auch in die Verarbeitung mit reinbringen das nich das ding. Dachte nur vielleicht gibts da ne andere möglichkeit weil wäre schicker wenns vorher geschieht und er nich bei der verarbeitung merkt das es an vorletzter Stelle jetzt dann noch falsch ist. Dann hätte man sich ja die vorherigen Rechnungen sparen könnnen. Naja und das mit 2^100 war wohl bissel übertrieben gesagt aber ich meinte das auch nur darauf bezogen das die Zahlen die normalen Zahlen Integer etc. sprängen würden ich kenn jetzt BigMath nich was da oben mal gennant wurde link ging da auch nicht. Müste ich jetzt mal googeln.
  Mit Zitat antworten Zitat
Reinhard Kern

Registriert seit: 22. Okt 2006
772 Beiträge
 
#7

Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?

  Alt 29. Nov 2007, 12:38
Zitat von Kenshin4455:
Danke erstmal für die Vorschläge!!

Prinzipell gings nur darum das ich nich alles durchgehen wollt. Grund ist das die Daten für die Verarbeitung korrekt vorliegen müssen sprich eine durchgängige Zahl ohne Buchstaben Sonderzeichen etc. dazwischen. ....
Hallo,

dein Ansatz bedeutet, alle korrekten Zahlen werden komplett 2 x gelesen, nur die unkorrekten nur einmal. Wenn du nicht gerade davon ausgehst, dass die Mehrzahl fehlerhaft ist, bringt das keinen Vorteil, sondern dauert länger.

Gruss Reinhard
  Mit Zitat antworten Zitat
Benutzerbild von LoCrux
LoCrux

Registriert seit: 5. Mär 2007
Ort: Gwang-Yang-City
48 Beiträge
 
Delphi 2009 Enterprise
 
#8

Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?

  Alt 29. Nov 2007, 12:57
@Der_Unwissende: LOGISCH!
“C++ is an insult to the human brain.” [Niklaus Wirth]

2B OR NOT 2B (.. THAT IS FF)
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#9

Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?

  Alt 29. Nov 2007, 13:10
Zitat von himitsu:
Delphi-Quellcode:
B := True;
For i := 1 to Length(S) do
  If not ((S[i] in ['0'..'9'])
    or ((i = 1) and (S[i] in ['+', '-']))) Then B := False;

If B Then {istZahl}
Das ist nicht so gut, da hier unter Umständen unnötig die or ((i = 1) and (S[i] in ['+', '-'])) Überprüfung gemacht wird. Die Braucht man nur einmal, aber unter Umständen wird jedes Mal überprüft ob i = 1 ist usw. Also entweder es vor der Schleife machen oder die Compilerdirektive (ich glaube) {$B-} davorstellen, so daß nicht alles verglichen wird.

Außerdem kann der Nullterminierte String nicht maximal 2^32 (bzw. erst bei 64 Bit 2^64) sein?

@Kenshin4455

Auch wenn es ein IN gäbe, glaubst du Delphi würde das per Gedankenlesen rausfinden? Es wäre dann intern ohne eigene Routine, aber eine Überprüfung würde es trotzdem geben. Und bei 4 GB wären das paar Minuten.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.374 Beiträge
 
Delphi 12 Athens
 
#10

Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?

  Alt 29. Nov 2007, 17:13
@LoCrux:
es stimmt schon das wenn Bit 6 nicht gesetzt ist daß es eine Zahl sein könnte, aber es muß dennoch keine Zahl sein (ih weiße da nur mal auf die ganzen Steuerzeichen #0..#31 hin),
also einfach nur Bit 6 zu Prüfen reicht nicht aus.

@Reinhard Kern:
Zitat:
Nebenbedingungen sind z.B. dass + und - nur am Anfang auftreten dürfen
tut es doch ... siehe (i = 1)

@Popov: hast schon Recht (es funktioniert zwar, aber wenn die 2 Assembleranweisungen je durchgang für i=1 gesparrt würde, dann wär's schon etwas optimaler)

Und es wäre bestimmt nicht schlecht, wenn bei Auffinden eines unzuläßigen Zeichens die Schleife abgebrochen (siehe Break) würde
Delphi-Quellcode:
B := (S <> '') and (S[1] in ['+', '-', '0'..'9']);
For i := 2 to Length(S) do
  If not (S[i] in ['0'..'9']) Then Begin
    B := False;
    Break;
  End;

If B Then {istZahl}
ein Punkt war zwar nicht mit in der "Aufgabenstellung" zu erkennen, aber was soll's:
Delphi-Quellcode:
B := (S <> '') and (S[1] in ['+', '-', '0'..'9']);
B2 := True;
For i := 2 to Length(S) do
  If not (S[i] in ['0'..'9']) Then
    If B2 and (S[i] = '.') and (i < Length(S)
      and (S[i - 1] in ['0'..'9'])
      and (S[i + 1] in ['0'..'9']) Then
      B2 := False
    Else Begin
      B := False;
      Break;
    End;

If B Then {istZahl}
oder
Delphi-Quellcode:
B := (S <> '') and (S[1] in ['+', '-', '0'..'9']);
B2 := True;
For i := 2 to Length(S) do
  If not (S[i] in ['0'..'9']) Then
    If B2 and (S[i] = '.') and (i < Length(S))
      and ((i > 2) or (S[1] in ['0'..'9'])) Then
      B2 := False
    Else Begin
      B := False;
      Break;
    End;

If B Then {istZahl}
oder das vorherigge nochmal mit PChar
Delphi-Quellcode:
Var P: PChar;
  i, i2: Integer;
  B, B2: Boolean;
i2 := Length(S);
P := PChar(S);
B := (i2 <> 0) and (P^ in ['+', '-', '0'..'9']);
B2 := True;
For i := 2 to i2 do Begin
  Inc(P);
  If not (P^ in ['0'..'9']) Then
    If B2 and (P^ = '.') and (i < i2)
      and ((i > 2) or (S[1] in ['0'..'9'])) Then
      B2 := False
    Else Begin
      B := False;
      Break;
    End;
End;

If B Then {istZahl}
(ich hoffe letzteres stimmt ... hab's jetzt nur aus'm Kopf umgeschrieben und nicht getestet)

und hier nochmal die PChar-Variante ohne Punkt:
Delphi-Quellcode:
Var P: PChar;
  i, i2: Integer;
  B, B2: Boolean;
i2 := Length(S);
P := PChar(S);
B := (i2 <> 0) and (P^ in ['+', '-', '0'..'9']);
For i := 2 to i2 do Begin
  Inc(P);
  If not (P^ in ['0'..'9']) Then Begin
    B := False;
    Break;
  End;
End;

If B Then {istZahl}
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:16 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz