Prüfen, ob String eine nichtnegative ganze Zahl enthält
- VB.NET
Sie verwenden einen veralteten Browser (%browser%) mit Sicherheitsschwachstellen und können nicht alle Funktionen dieser Webseite nutzen.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Es gibt 54 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.
-
-
VaporiZed schrieb:
Aber was hat es mit dem y überhaupt auf sich?
Eigentlich nur um Nachkommastellen auszuschließen. Sind Integerwert und Doublewert gleich handelt es sich um eine Ganzzahl oder wie oben beschrieben: Bleibt bei der Division des Doublewerts durch den Integerwert kein Rest, sind die Zahlen identisch.
Ein Computer wird das tun, was du programmierst - nicht das, was du willst. -
ErfinderDesRades schrieb:
Hier sind jetzt so einige "Lösungen" vorgestellt worden, andere nicht, und mich würd jetzt malwieder interessieren,- wie nun die letztendliche Aufgabenstellung lautet
- wie Peter329s letztendliche Lösung dazu aussieht
Die Aufgabenstellung ist doch ganz einfach:
Ein Textfeld wird mit.ToString("n0")
befüllt. Damit wird eine GanzZahl mit Tausender Trennzeichen angezeigt.
Der Anwender kann diese Zahl beliebig abändern. Ich möchte prüfen, ob die Eingabe korrekt ist. Alle Eingaben, die "normale" Menschen als "richtig" ansehen würden, sollen akzeptiert werden. Punkt und Komma, sollen gemäß der aktuellen "Culture" interpretiert werden.
Gültig sind (mit deutscher Culture):
2925
217
30.500.072
18,0
+320
+ 27
Ungülitg sind
1a7
18,3
-19
++30
.200
168.192.0.1
240. 192.100.200
Das ist mein Coding:
VB.NET-Quellcode
- Public Function IsWholeNonNegative(s As String, ByRef x As Integer) As Boolean
- 'Initialize return value
- x = 0
- 'Check input is numeric
- If Not Int32.TryParse(s,
- NumberStyles.Any,
- Thread.CurrentThread.CurrentCulture,
- x) Then Return False
- 'Check input is a whole number
- Dim y As Double = 0
- If Not Double.TryParse(s, y) AndAlso y Mod x = 0 Then Return False
- 'Check input is non negative
- If Not x >= 0 Then Return False
- 'Check format (thousand separarators and + sign)
- Dim ss = s.Split(","c) 'Remove decimal comma
- Dim blk = ss(0).Split("."c) 'Get blocks of thousand
- Dim cnt = blk.Length 'Get number of blocks
- If cnt > 1 Then 'Thousand separators specified
- If blk(0).StartsWith("+") Then _
- blk(0) = blk(0).Substring(1).Trim 'Remove one leading + sign
- Dim l = blk(0).Length 'Check length first of block (1 - 3)
- If Not (1 <= l AndAlso l <= 3) Then Return False
- End If
- For i = 1 To cnt - 1 'Check length of subsequent blocks (3)
- If blk(i).Length <> 3 Then Return False
- Next
- 'Check completed
- Return True
- End Function
Verbesserungsvorschläge sind willkommen.
LG
Peter
Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Peter329“ ()
- wie nun die letztendliche Aufgabenstellung lautet
-
Wenn die Aufgabenstellung so einfach ist, wie du denkst, warum hast du das nicht bereits im Eröffnungspost schon reingeschrieben?
Ich denke, dass die Antworten ganz anders ausgesehen hätten. Niemand hat sich die Frage gestellt, wie genau der Inhalt deiner Textbox zustande kommt.
Die Information, dass es sich hierbei um eine aktive Erfassung von Werten handelt ist deswegen wesentlich, weil man hier bereits ansetzen könnte.
Man kann einer Textbox durchaus sagen, dass sie auf das Textchange Ereignis reagieren soll (weil das auch reinkopierten Text erfasst, es gibt auch andere Ereignisse die hierfür geeignet wären) und einfach nur bestimmte Zeichen überhaupt erlauben soll. Das erleichtert das spätere Parsen ungemein.
Mit anderen Worten, die erste Frage von @ErfinderDesRades im Post 21 ist die wichtigste Frage überhaupt, nur hat sie niemand gestellt. Und du gingst mal eben einfach so davon aus, dass es klar sei. -
Boah, die Anforderungen sind aber doch größer als erwartet.
+ 27
soll akzeptiert werden, weil es eine Schreibweise ist,Peter329 schrieb:
die "normale" Menschen als "richtig" ansehen würden
Was ist mit10e12
,2^23
?
->If x < 0 Then Return False
Aber ohne es ausgetestet zu haben: Ab Z#18 ist doch kein Weiterkommen. Die ganzen Textspielereien müssten doch vor der Zahlumwandlung hin. Ein+ 23
würde es nie bis Z#18 schaffen.
Das mit dem Double kapier ich immer noch nicht. Wenn ein Text nicht in einen Integer geparst werden kann (Z#7), dann bringt doch das Parsen in einDouble
nix. Selbst wenn da rauskäme, dass der Text in ein Double konvertiert werden kann: Was nützt Dir dieses Wissen?
Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.
Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln. -
Erst mal Danke, dass ihr euch mit meinem Anliegen befasst habt.
@Dksksm: das mit dem Abfangen von Eingaben ist halt eine Frage der "Usability" ... ich halte nichts davon, weil das fehlerträchtig ist ! Wenn der Anwender etwa 67k239 eingibt und ich das "k" z.B. per KeyPress unterdrücke, dann lautet die Eingabe 67239 ... und damit kann ein Fehler unentdeckt bleiben. Ich nehme User Eingaben immer so entgegen wie sie sind und verändere sie auch nicht im Program. Das erleichtert nicht zuletzt das Debugging.
@VaporiZed: das mit der Abfrage "not x >=0" verwende ich ganz bewusst ! Ich schreibe immer die Bedingung, die ERFÜLLT sein soll ... und frage dann mit NOT ab, ob sie NICHT erfüllt ist. Das ist halt eine Konvention, die ich für sinnvoll halte - auch wenn man das anders sehen kann. Aber es ist besser eine einheitliche CodeTechnik zu verwenden als ständig den Stil zu wechseln.
Tatsächlich hat @VaporiZed Recht ... die Sache mit dem "modulo" ist nicht notwendig, weil das schon vom Int32.TryParse abgefangen wird. Also raus damit.
VaporiZed schrieb:
Aber ohne es ausgetestet zu haben: Ab Z#18 ist doch kein Weiterkommen.
Das solltest du aber testen.
Die Eingabe 1.2.3 liefert nämlich 123 ... und das würden normal denkende Menschen nicht als richtig ansehen.
Exponentielle Schreibweisen z.B. 2e5 oder Rechenausdrücke z.B. 2^8, würden normale Leute nicht verwenden. Blöderweise akzeptiert TryParse 2e5 ... das muss man also abfangen.
So sieht meine Routine jetzt aus:
VB.NET-Quellcode
- Public Function IsWholeNonNegative(str As String, ByRef x As Integer) As Boolean
- 'Initialize return value
- x = 0
- 'Check valid digits
- Dim s = str.Trim 'Remove leading and trailing spaces
- If s.StartsWith("+") Then s = s.Substring(1).Trim 'Remove + sign
- Dim ValDigits = "0123456789.,"
- For i = 0 To s.Length - 1
- If Not ValDigits.Contains(s(i)) Then Return False
- Next
- 'Check input is a whole number
- If Not Int32.TryParse(s,
- NumberStyles.Any,
- Thread.CurrentThread.CurrentCulture,
- x) Then Return False
- 'Check input is non negative
- If Not x >= 0 Then Return False
- 'Check format (thousand separarators and + sign)
- Dim blk = s.Split("."c) 'Get blocks of thousand
- Dim cnt = blk.Length 'Get number of blocks
- If cnt > 1 Then 'Thousand separators specified
- Dim l = blk(0).Length 'Check length first of block (1 - 3)
- If Not (1 <= l AndAlso l <= 3) Then Return False
- End If
- For i = 1 To cnt - 1 'Check length of subsequent blocks (3)
- If blk(i).Length <> 3 Then Return False
- Next
- 'Check completed
- Return True
- End Function
Gibt es Verbesserungsvorschläge ?
LG
Peter
Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von „Peter329“ ()
-
Peter329 schrieb:
Die Aufgabenstellung ist doch ganz einfach
aber eindeutig formuliert ists erst in post#23 - soweit ich sehe.
-
@Peter329 Wenn da in der
TextBox
noch editiert werden darf, dann lass doch einfach nur Tastendrücke zu, die zu einer UInteger-Zahl passen: 0...9 und Editier-Tasten und desgleichen bei C&P und feddich.
Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
-
Peter329 schrieb:
Das solltest du aber testen. Die Eingabe 1.2.3 liefert nämlich 123 ... und das würden normal denkende Menschen nicht als richtig ansehen+ 23
durchkommt. Das scheiterte aber mit demInteger.TryParse
schon vorher. Mit dem jetzigen Code geht es. Weil Du einen Teil der Textbearbeitung vor das Parsen gestellt hast.
Das mit derNot Sollbedingung
ist Deine Codekonvention, ok, das war mir nicht klar. Daran will ich natürlich nicht rütteln.
Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.
Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln. -
Peter329 schrieb:
Ungülitg sind
-19
LG
Peter
aber in der Buchhaltung und in vielen anderen Bereichen müssen negative Zahlen erlaubt sein
eigenartige Anforderung die du da hast
-
Da wir den Anwendungsfall nicht kennen, aber seit Post#1 klar ist, dass eine positive Ganzzahl rauskommen soll, widerspreche ich dem Einwand. Kaufmännisch wird da sicher nix ablaufen.Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.
Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln. -
Kasi schrieb:
aber in der Buchhaltung und in vielen anderen Bereichen müssen negative Zahlen erlaubt sein
eigenartige Anforderung die du da hast
nur spaßeshalber:
auch in der Buchhaltung gibt es Felder, die nicht-negativ und ganzzahlig sein müssen ... z.B. in der Bestandsführung ,,, -2,7 Kraftfahrzeuge wird die Betriebsprüfung vermutlich nicht so ganz akzeptieren.
In meinem Fall, enthält das Textfeld übrigens einen Zähler ... da ist meine Anforderung vielleicht nicht gar so eigenartig.
Aber jetzt habe ich doch noch eine Frage:
Zeile 24:
Diese Anweisung ist natürlich nur richtig, wenn die Culture PUNKTE als Tausender Trennzeichen verwendet.
Das ist in der "deutschen Culture" (die ich verwende) der Fall. Wie das in anderen Cultures aussieht weiß ich nicht. Und alle Cultures daraufhin überprüfen möchte ich (faul wie ich nun mal bin) auch nicht ! Zumal sich das ja auch irgendwann ändern könnte.
Mit anderen Worten: Wie kann ich herausfinden, ob ein Punkt oder ein Komma als Tausender Trennzeichen verwendet wird ... ?
Natürlich könnte ich Cint("1000").ToString("n0") verwenden, um das per Substring heraus zu kriegen. Aber das ist "schweinisch" ... und mir liegt doch sehr an anständigem Coding ...
Weiß jemand wie ich das mit "regulären" Befehlen hin bekommen ?
LG
Peter
Dieser Beitrag wurde bereits 8 mal editiert, zuletzt von „Peter329“ ()
-
Peter329 schrieb:
-2,7 KraftfahrzeugeNumericUpDown
verwenden, maximale obere Grenze und feddich.Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.
Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln. -
@RFG
Na ja, ein NumericUpDown wäre schon eine Alternative. Da erhalte ich eine Ganzzahl aus einem definierten Intervall ...
Wenn das Werte zwischen 0 und 10 betrifft ist das schon in Ordnung. Aber mein Zähler kann durchaus Wert von mehreren Millionen enthlalten. Ich weiß nicht, ob irgend jemand so einen NumericUpDown als "user friendly" bezeichnen würde. ich erwarte da ganz andere Stellungnahmen ...
@VaporiZed
Jip ... das war die Anweisung, die ich gesucht hatte.
Damit bin ich völlig happy. Alles in allem wieder mal ein geradezu klassisches Beispiel dafür, wie die geballte Schwarmintelligenz eines Forums dazu in der Lage ist, ein recht komplexes Problem punktgenau zu lösen.
DANKE !
LG
Peter
LG
Peter
-
Das NUD-Argument versteh ich nicht. Man muss die Pfeiltasten ja nicht nutzen. Man kann ja selber eintippen und Ober- und Untergrenze festlegen. Es geht ja nur darum, dass das NUD eben nur Zahlen in einem gewissen Bereich akzeptiert. Aber das hatte ich ja in Post#6 schon erwähnt.
Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.
Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln. -
Peter329 schrieb:
Aber mein Zähler kann durchaus Wert von mehreren Millionen enthlalten.NumericUpDown.Value
undNumericUpDown.Maximum
sind vom TypDecimal
.
Sieh Dir mal an, was da alsDecimal.MaxValue
möglich ist.
====
10000000000000000000000000000
funktioniert als NUD.MaxValue.
Decimal.MaxValue = 79228162514264337593543950335
funktioniert auch.
Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert!Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()
-
Und auf welchen Wert wirst du die Obergrenze festlegen ? Na gut, eben auf den Maximalwert eines Integer ... auch wenn das dann weit jenseits von "Gut und Böse" ist.
Aber von mir aus ... dann ist ein NumericUpDown eben eine Alternative.
Für meinen Geschmack ist das halt eher "user friendly", wenn ich den aktuellen Wert anzeige und den User OHNE up-and-down einen neuen Wert eintippen lasse - weil sich der Wert ohnehin üblciherweise gravierend vom angezeigten Wert unterscheiden wird. Aber das ist halt von den Besonderheiten der Anwendung abhängig und ansonsten Geschmackssache. Und über Geschmack lässt sich bekanntlich nicht streiten.
Die prinzipielle Auigabe, einen String auf die Eigenschaft "IsWholeNonNegative" zu prüfen, halte ich inzwischen für ausdiskutiert. Es sei denn, jemand hätte da jetzt noch einen wesentlich neuen Gesichtspunkt einzubringen.
LG
Peter
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Peter329“ ()
-
@Peter329 Mach die Obergrenze hinreichend groß, 10 * Dein persönliches Maximum.
Frag Frau Google nachvb.net numericupdown ohne spinbutton
Sieh mal hier: NumericUpDown-Steuerelement ohne Drehfeld möglich?
ich weiß aber nicht, obs gelöst wurde.Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert!
-
Ähnliche Themen
-
Gelöschter Benutzer - - Sonstige Problemstellungen
-
Zahl auf Nachkommastellen prüfen
TheoTechnic - - Sonstige Problemstellungen
-
10 Benutzer haben hier geschrieben
- Peter329 (18)
- RodFromGermany (10)
- VaporiZed (9)
- ErfinderDesRades (8)
- Yanbel (3)
- xChRoNiKx (2)
- nafets (2)
- Kasi (1)
- Dksksm (1)
- Bluespide (1)