Seite 1 von 2

Variable numerisch ??

Verfasst: 24.02.2005 17:52
von i.j.radtke
Wie kann ich prüfen ob eine Stringvariable einen numerischen oder alphanumerischen Wert angenommen hat ??

Verfasst: 24.02.2005 18:36
von Kaeru Gaman
meinst du, ob ein string nur zahlen enthält oder noch was anderes?

oder auch, ob diese zahl einen gültigen wert hat...

vielleicht hilft dir das:

Code: Alles auswählen

a$ ="12345"
b$ ="hallo"
c$ ="12345hallo"
d$ ="-37.5"
e$ ="521.764.738"

Debug Val(a$)
Debug Val(b$)
Debug Val(c$)
Debug Val(d$)
Debug Val(e$)

Debug "---------------"

Procedure CheckStrNum(Given.s)

    Lang = Len(Given)           ; Länge

    P1 = Asc(Left(Given,1))     ; erstes zeichen

    If (P1<48 Or P1>57) And P1 <> 45 And P1 <> 46   ; nicht 0-9 o. "-" o. "."
        Test = -1                                   ; fehler
    EndIf
    
    If Given = "-" Or Given = "." Or Given = "-."   ; "-" oder "." einzige zeichen?
        Test = -1                                   ; fehler
    EndIf
    
    If p1 = 46      ; dezimalpunkt?
        Decim = 1   ; flag "punkt war schon"
    EndIf
    
    If Test = 0 And Lang > 1    ; erstes zeichen numerisch und weitere vorhanden?
        For i=2 To Lang
            PA = Asc(Mid(Given,i,1))
            If (PA<48 Or PA>57) And PA <> 46    ; nicht 0-9 oder "."
                Test = -1                       ; fehler
            EndIf
            If PA = 46          ; dezimalpunkt?
                If Decim = 0    ; war noch nicht?
                    Decim = 1   ; merken
                Else            ; war schon?
                    Test = -1   ; fehler
                EndIf
            EndIf
        Next
    EndIf

    ProcedureReturn Test

EndProcedure

Debug CheckStrNum(a$)
Debug CheckStrNum(b$)
Debug CheckStrNum(c$)
Debug CheckStrNum(d$)
Debug CheckStrNum(e$)
hab die Proc extra ausführlich gemacht, man kann da zusammenfassen.

das erste zeichen wird extra geprüft, damit es ein "-" sein kann...

PS: oops, sehe grad... dezimalpunkt ist nicht drin... ich änder mal...

PPS: So, jetzt kann genau ein Dezimalpunkt drin vorkommen...

PPPS: noch eine änderung: minus und/oder dezimalpunkt ohne ziffern ist auch keine zahl.


man kann das einsetzen z.b. durch:

Code: Alles auswählen

If CheckStrNum(Bla$)
    BlaVal = Val(Bla$)
EndIf
ein overflow wird aber hier nicht gepuffert...

also, der string kann auch "63498716324973216591287659324562439928546" sein,
aber den Val() kann man nicht einer Long zuweisen...

Verfasst: 25.02.2005 02:37
von ts-soft
ob numerisch ist kannste so feststellen: (nicht für fließkommazahlen)

Code: Alles auswählen

Procedure IsNumeric(Text.s)
  Result = #True
  For I = 1 To Len(Text)
    J.s = Mid(Text, I, 1)
    If (Asc(J) < 58 And Asc(J) > 47) = #False
      Result = #False
    EndIf
  Next
  ProcedureReturn Result
EndProcedure
und für Alphanumerisch mithilfe der API:

Code: Alles auswählen

Procedure IsAlphaNumeric(Text.s)
  Result = #True
  For I = 1 To Len(Text)
    J.s = Mid(Text, I, 1)
    If IsCharAlphaNumeric_(Asc(J)) = #False
      Result = #False
    EndIf
  Next
  ProcedureReturn Result
EndProcedure

Verfasst: 25.02.2005 02:44
von Falko

Code: Alles auswählen

;Falko  PB3.93b ohne API
;Unterscheidet zwischen Alpha und Nummeric (Buchstaben oder Zahlen ohne Vorzeichen,Punkt und Komma).
;Will man einen auch Andere Zeichen einsetzten kann
;Man das mit Hilfe der ASCII-Tabelle leicht erweitern.
;Hier habe ich nur zwiechen Zahlen ohne Leerzeichen und Buchstaben 
;ein Beispiel gemacht.

String1.s="123Alphanumerisch 2"
String2.s="Mein Text ohne Zahlen"
String3.s="9805"
String4.s="   "
Procedure.l Get_Alpha_Num(Stringvariable.s)
  Num.b=0:Alpha.b=0:Resume.b=0
  For i = 1 To Len(Stringvariable)
    ;-liest und prüft die einzelnen Buchstaben und Zahlen
    If Asc(Mid(Stringvariable,i,1)) >= 44 And Asc(Mid(Stringvariable,i,1)) <=57
       If Asc(Mid(Stringvariable,i,1))=47 : Break :EndIf ; Schmeiß das '/' raus
       Num=1
    EndIf
    
    If Asc(Mid(Stringvariable,i,1)) >= 65 And Asc(Mid(Stringvariable,i,1)) <=154
      Alpha=1
    EndIf
    ;-Unterscheidung von Alpha,Num,beides oder Nichts
    If Num=1 And Alpha=1
      Resume = 1
    ElseIf Num=0 And Alpha=1
       Resume = 2
    ElseIf Num=1 And Alpha=0
      Resume = 3
    Else
      Resume = 0
    EndIf  
  Next 
  ProcedureReturn Resume
 EndProcedure
 
 Debug String1 + Space(6) + ":"+ Str(Get_Alpha_Num(String1)) ; Rückgabe sollte 1 für Alphanummerisch sein
 Debug String2 + Space(3)+":"+Str(Get_Alpha_Num(String2)) ; Rückgabe sollte 2 für Alpha sein
 Debug String3 + Space(32)+":"+Str(Get_Alpha_Num(String3)) ; Rückgabe sollte 3 für nummerisch sein
 Debug String4 + Space(37)+":"+Str(Get_Alpha_Num(String4))      ; 0 Ausserhalb wenn andere Zeichen kommen.
[EDIT]
Bitte nicht schimpfen, wenn mein Code zu lang ist und die CPU
dadurch ans Arbeiten kommt. Aber es geht nur um das Verständnis, nicht
um die Geschwindigkeit
:mrgreen:
[/EDIT]

Verfasst: 25.02.2005 03:13
von Deeem2031
Finds ja gut wenn Leute helfen wollen, aber wenn dann sowas CPU fressendes wie der Code von Falko kommt :freak:

Ein "bischen" schneller gehts z.B. so:

Code: Alles auswählen

Procedure.l Get_Alpha_Num(Stringvariable.s)
  Protected result,*p.BYTE
  
  *p = @Stringvariable
  While *p\b
    ;-liest und prüft die einzelnen Buchstaben und Zahlen 
    If *p\b >= 44 And *p\b <=57 
      result|1 
    ElseIf *p\b >= 65 And *p\b <=154 
      result|2
    EndIf 
    *p+1
  Wend
  
  ProcedureReturn result
EndProcedure
Das ist natürlich schon etwas kompliziert, für Anfänger also eher nicht geeignet.
Aber warum schreibst du in jedem Schleifendurchlauf die Variable Resume neu?
Warum benutzt du Bytes?
"Asc(Mid(Stringvariable,i,1))" in einer Variablen zu speichern, beschleunigt das ganze auch erheblich.
...

Man sollte wenigstens versuchen seinen Code zu optimieren, besonders wenn er als Beispiel dienen soll.


Sry, aber das musste ma sein...

Verfasst: 25.02.2005 03:29
von ts-soft
Ich hätte beim Treffer ja noch ein Break einsetzen können, um unnötige Schleifendurchläufe zu sparen, aber dann funktioniert es vielleicht in älteren PB-Versionen nicht. Und das pointern fand ich in diesem Forum nicht angebracht

[Edit]Nachtrag: hab's gerade von Deeem2031 getestet, ist zwar schnell, aber Umlaute usw. werden nicht berücksichtig. Deshalb hab ich in diesem Fall die API-Funktion genommen, sonst würde der Code doch ziemlich lang werden. Ländereinstellungen testen usw. [/Edit]

Verfasst: 25.02.2005 13:54
von Mischa
Um lediglich festzustellen ob ein string ganzzahlig numerisch
ist, wäre diese Möglichkeit noch 'n Tucken schneller und vor allem
kürzer.

Code: Alles auswählen

Procedure IsNumeric(string.s)
  If string=Str(Val(string))
    ProcedureReturn 1
  EndIf
EndProcedure
Gruß,
Mischa

Verfasst: 25.02.2005 14:14
von Kaeru Gaman
@Falko
> If Asc(Mid(Stringvariable,i,1)) >= 44 And Asc(Mid(Stringvariable,i,1)) <=57

@Deem
> If *p\b >= 44 And *p\b <=57

seit wann ist der slash "/" Chr(47) ein numerisches zeichen?
und wieso sollten in einer zahl mehrere minus und kommata vorkommen?

btw:
afaik bezeichnet 'Alphanumerisch' jeglichen ascii-code, nicht nur buchstaben des alphabets, oder????? :shock:

@Mischa
guter trick, schön kurz und knackig :allright:


und wieso sagt keiner was zu meinem code? :?
habt ihr angst vor mir? :twisted: ( :wink: :mrgreen: )

Verfasst: 25.02.2005 14:58
von bluejoke
afaik bezeichnet 'Alphanumerisch' jeglichen ascii-code
Kann sein, aber doch sicherlich nicht die Steuerzeichen, die ja auch im Ascii-Code vorliegen!


Verfasst: 25.02.2005 15:27
von Falko
Kaeru Gaman hat geschrieben:@Falko
> If Asc(Mid(Stringvariable,i,1)) >= 44 And Asc(Mid(Stringvariable,i,1)) <=57

@Deem
> If *p\b >= 44 And *p\b <=57.......

....und wieso sagt keiner was zu meinem code? :?
habt ihr angst vor mir? :twisted: ( :wink: :mrgreen: )
@Kaeru Gaman

Geht es darum wer am besten kürzen kann, weils für Spiele schneller und
kleiner ist, oder eher, einem, der mit PB anfängt es verständlich zu machen?
Sicher ist jeder Soruce-Code hier sehr gut. Das mit dem '/' kann man doch jederzeit rausnehmen. Habs oben noch eingefügt.

:mrgreen: hat doch keiner gesagt das dein Code schlecht ist. Dagegen ist meiner wirklich eine Bremse (Absicht).

MfG Falko