Variable numerisch ??

Anfängerfragen zum Programmieren mit PureBasic.
i.j.radtke
Beiträge: 9
Registriert: 24.02.2005 17:50
Wohnort: MVP

Variable numerisch ??

Beitrag von i.j.radtke »

Wie kann ich prüfen ob eine Stringvariable einen numerischen oder alphanumerischen Wert angenommen hat ??
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag 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
Zuletzt geändert von ts-soft am 25.02.2005 03:07, insgesamt 1-mal geändert.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Beitrag 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]
Zuletzt geändert von Falko am 25.02.2005 15:15, insgesamt 5-mal geändert.
Bild
Win11 Pro 64-Bit, PB_6.11b1
Benutzeravatar
Deeem2031
Beiträge: 1232
Registriert: 29.08.2004 00:16
Wohnort: Vorm Computer
Kontaktdaten:

Beitrag 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...
Bild
[url=irc://irc.freenode.org/##purebasic.de]irc://irc.freenode.org/##purebasic.de[/url]
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag 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]
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Mischa
Beiträge: 152
Registriert: 29.08.2004 06:52
Wohnort: Hellhorst

Beitrag 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
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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: )
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
bluejoke
Beiträge: 1244
Registriert: 08.09.2004 16:33
Kontaktdaten:

Beitrag von bluejoke »

afaik bezeichnet 'Alphanumerisch' jeglichen ascii-code
Kann sein, aber doch sicherlich nicht die Steuerzeichen, die ja auch im Ascii-Code vorliegen!

Ich bin Ausländer - fast überall
Windows XP Pro SP2 - PB 4.00
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Beitrag 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
Bild
Win11 Pro 64-Bit, PB_6.11b1
Antworten