Today's question.
Freebasic has an IsDate function, but nothing for IsNumber, afaik. It is quite possible for a user to enter a number with more than one decimal point or alphabetic characters in a field, and conversions, such as Val(astring) will result in a valid number, up to the first error character.
Some systems I have used prevent the entry of any characters which are not numbers, others insist on deleting the existing entry before entering the new, other send warning beeps, etc.
I'm not sure if there is recommended parsing strategy in freebasic, but what I've done is convert the string to a number, then convert said number back to a string and compare with original string. I had to do a bit of extra stripping of zeros from leading and trailing part of original string, check for more than one decimal point, and adjust the string so that that decimal numbers began with '0.nnnn' cf '.nnnn' and ended as 'nnnn' cf 'nnnn.' I am not interested in '+' or '-', entry as those will be treated as non numeric, but that can be easily altered.
So, is there a more succinct method of validating numeric entries?
I think this is maybe what you are looking for?
http://www.planetsquires.com/protect/forum/index.php?topic=2916.msg21686#msg21686
I wrote in PB but it should be very easy to convert to FB.
thanks. I had thought of testing each character of the string, but hadn't cottoned on with the select/case method, being stuck with thinking of instr. It probably won't make much difference to my simple program, but I may substitute a version of what you have suggested for my solution, just for the sake of trying it out.
for the sake of completeness, here is my original code, which works fine for what I want. I call it as the textbox is read, and if it is not a valid number, I change the background colour of the textbox. Basically it compares the way in which fb converts a number to a text string, compared to how the text is originally entered by the user. It could be fine tuned to be consistent with + and - (+ is assumed in converting a value to a string - if the user enters '+' it is shown as an error) Also, for my particular application, a data entry value of zero is not allowed. Function isnotanumber(a as String) as boolean ' checks if valid decimal number.
'returns false if a number
Dim r as String ' result string
Dim dpc as Integer = 0 ' decimal point count
If (Val(a) =0.0) Then Return True 'not allow zero
a= LTrim (RTrim (a,"0"),"0") 'remove leading/trailing 0's
r=Str(Val(a)) 'get string from value a
dpc=InStr(1,a,".") 'check for only 1 dp
If dpc<>0 Then
dpc=InStr(dpc+1, a,".")
If dpc<>0 Then
Return True 'return true for more dp's
End If
End If
'correct for leading and trailing decimal point
If (Left(a,1) =".") Then a="0"+a 'put 0 in front of dp
If (Right(a,1) =".") Then a = Left (a, Len(a)-1) 'remove dp if last char
If (r<> a) Then Return True
Return False
End Function
Certainly many ways that you can accomplish it. Whichever way works and is easy to read and understand certainly is the way to go.
For the fun of it, I modified your code ever so slightly while still preserving the overall intent and logic of your code. Notice my use of TRIM, LTRIM and RTRIM using the second parameter to remove characters other than a space. Also, look at how I searched the string for multiple period characters. In FB, you can traverse a string using array indexing directly without first having to create a byte pointer. Pretty cool and useful.
Function isnotanumber(ByRef a As String) As boolean ' checks if valid decimal number.
' returns false if a number
Dim r As String ' result string
Dim dpc As Integer = 0 ' decimal point count
If Val(a) = 0 Then Return True 'not allow zero
a = Trim(a, "0") 'remove leading/trailing 0's
r = Str(Val(a)) 'get string from value a
For i As Long = 0 To Len(a) - 1
If a[i] = 46 Then dpc += 1 ' look for periods (ascii(46))
If dpc > 1 Then Return True
Next
' correct for leading and trailing decimal point
If Left(a, 1) = "." Then a = "0" + a 'put 0 in front of dp
If Right(a,1) = "." Then a = Rtrim(a, ".") ' remove ending decimal
If r <> a Then Return True
Return False
End Function
Print isnotanumber("0")
Print isnotanumber("03as.3")
Print isnotanumber("0.44.5")
Print isnotanumber("99.345")