Test that a string value has an integer format ?

Just starting out? Need help? Post your questions and find answers here.
Neil
Enthusiast
Enthusiast
Posts: 198
Joined: Wed Feb 29, 2012 8:04 am
Location: Melbourne, AUS

Test that a string value has an integer format ?

Post by Neil »

Hi All,

Sorry if this is a simple question that has been answered before, but I couldn't find any references as it is hard to describe the question exactly.

How can I check if the value of a string has an integer format ??

e.g. String.s = "1"

Check that value of the string is an integer format, i.e. not "1.5" or "abc"

Thanks,

Neil
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Test that a string value has an integer format ???

Post by luis »

There are many ways, more or less fast, more or less compact.
Here is one:

Code: Select all

Procedure.i IsCharDigit (Char.c)
; [DESC]
; Check if the passed character is a digit.
;
; [INPUT]
; Char : The char to be checked.
;
; [RETURN]
; 1 if it is a digit, else 0.
 
 If Char >= '0' And Char <= '9'
    ProcedureReturn #True
  EndIf
 
 ProcedureReturn #False
EndProcedure

Procedure.i IsCharAlfa (Char.c)
; [DESC]
; Check if the passed character is alphabetic.
;
; [INPUT]
; Char : The char to be checked.
;
; [RETURN]
; 1 if it is alphabetic, else 0.
 
 If Char >= 'a' And Char <= 'z'
    ProcedureReturn #True
  EndIf

 If Char >= 'A' And Char <= 'Z'
    ProcedureReturn #True
  EndIf
 
 ProcedureReturn #False
EndProcedure

Procedure.i IsStringDigits (S$)
; [DESC]
; Check if the passed string is composed of digits only.
;
; [INPUT]
; S$ : The string to be checked.
;
; [RETURN]
; 1 if the string is composed of only digits, else 0.

 Protected *char.Character = @S$
 
 While *char\c    
    If IsCharDigit(*char\c) = #False 
        ProcedureReturn #False
    EndIf    
    *char + SizeOf(Character)
 Wend
 
 ProcedureReturn #True
EndProcedure

Procedure.i IsStringAlpha (S$)
; [DESC]
; Check if the passed string is composed of alphabetic chars only.
;
; [INPUT]
; S$ : The string to be checked.
;
; [RETURN]
; 1 if the string is alphabetic, else 0.

 Protected *char.Character = @S$
 
 While *char\c    
    If IsCharAlfa(*char\c) = #False 
        ProcedureReturn #False
    EndIf    
    *char + SizeOf(Character)
 Wend
 
 ProcedureReturn #True
EndProcedure
"Have you tried turning it off and on again ?"
swan
Enthusiast
Enthusiast
Posts: 226
Joined: Sat Jul 03, 2004 9:04 am
Location: Sydney Australia
Contact:

Re: Test that a string value has an integer format ???

Post by swan »

Have a search under "isnumeric".
Here's one post - http://www.purebasic.fr/english/viewtop ... c+String.s+
User avatar
JHPJHP
Addict
Addict
Posts: 2258
Joined: Sat Oct 09, 2010 3:47 am

Re: Test that a string value has an integer format ???

Post by JHPJHP »

Last edited by JHPJHP on Thu Jul 11, 2013 9:22 pm, edited 1 time in total.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
Neil
Enthusiast
Enthusiast
Posts: 198
Joined: Wed Feb 29, 2012 8:04 am
Location: Melbourne, AUS

Re: Test that a string value has an integer format ???

Post by Neil »

luis wrote:

Code: Select all

??? Protected *char.Character = @S$
 
??? While *char\c   
???    If IsCharDigit(*char\c) = #False 
        ProcedureReturn #False
    EndIf   
???    *char + SizeOf(Character) 
 Wend
Hi Luis,

Thanks for prompt and interesting reply.

Some questions:

1. What is the best way to check for negative integer values, i.e. if string = "-2", return #true.

2. What is happening in the code lines marked with "???". I know that you are using pointers and I can read descriptions of them in the manual, but I still don't really understand the reasons for using them. Understanding what you have done in this snippet should help a lot.

Thanks,

Neil
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Test that a string value has an integer format ???

Post by luis »

Neil wrote: 1. What is the best way to check for negative integer values, i.e. if string = "-2", return #true.
Don't know about the best, since the definition of best depends on the requirements, yourself, etc.
One way is to simply modify IsStringDigits() to check if the first char is a sign and accept it as valid.
Neil wrote: 2. What is happening in the code lines marked with "???". I know that you are using pointers and I can read descriptions of them in the manual, but I still don't really understand the reasons for using them. Understanding what you have done in this snippet should help a lot.
Instead of using Mid(), Left(), Right() and so on you can use pointers (to chars in this case) to scan the string.
To do so you need a pointer to char initialized to the start of the string buffer and you need to move through the buffer incrementing that pointer.
The increment is done using the Sizeof operator instead of a simpler +1 because Char is defined to be 1 byte big in ascii and 2 bytes big in unicode (see help about data types).
This way the code works in both environments.
Why use pointers instead of the mentioned Mid() etc ? Essentially because incrementing a pointer with a linear access in memory is faster the calling a function like Mid(), and more importantly any string function like Mid() create a new string to return the result. Using pointers you just look at the already existing source string. Much more efficient.
In the code above I have a call to an helper function anyway (IsCharDigit), but this way is more modular, you can move its code inside the main proc to speed it up. Anyway, this was not made with speed in mind (very rarely I code looking for the faster code) , but using pointers came to no cost so why don't do it.

Nothing wrong in using mid() anyway, depends on the buffer size, how many times you call it, etc.
For checking a user input for example, all this makes no difference. It's just a good habit that can help you in writing better code later on.


Oh, forgot. The while terminates ad the end of the string because PB string are null terminated (the last char is a binary 0).
So when the pointer reaches it, the expression in the while becomes false.

Hope this helps, I'm going to sleep so if you have other question I'll read them tomorrow, or someone else will help you for sure.

Goodnight.... ronf....
"Have you tried turning it off and on again ?"
citystate
Enthusiast
Enthusiast
Posts: 638
Joined: Sun Feb 12, 2006 10:06 pm

Re: Test that a string value has an integer format ???

Post by citystate »

I use a RegEx:

Code: Select all

Procedure IsNumeric(string.s)
  rx=CreateRegularExpression(0,"^(-)?(\d)+(\.)?(\d)*$")
  x=MatchRegularExpression(0,Trim(string))
  FreeRegularExpression(0)
  ProcedureReturn x
EndProcedure

Debug IsNumeric("236523")
Debug IsNumeric("-3232")
Debug IsNumeric("0.0")
Debug IsNumeric("-10.02")
Debug IsNumeric("0.0a")
there is no sig, only zuul (and the following disclaimer)

WARNING: may be talking out of his hat
Neil
Enthusiast
Enthusiast
Posts: 198
Joined: Wed Feb 29, 2012 8:04 am
Location: Melbourne, AUS

Re: Test that a string value has an integer format ???

Post by Neil »

citystate wrote:I use a RegEx:

Code: Select all

Procedure IsNumeric(string.s)
  rx=CreateRegularExpression(0,"^(-)?(\d)+(\.)?(\d)*$")
  x=MatchRegularExpression(0,Trim(string))
  FreeRegularExpression(0)
  ProcedureReturn x
EndProcedure

Debug IsNumeric("236523")
Debug IsNumeric("-3232")
Debug IsNumeric("0.0")
Debug IsNumeric("-10.02")
Debug IsNumeric("0.0a")
Hi Citystate,

Very nifty !!

But I would like test 3 & 4 to be false as well !!

i.e. I would like to be able to check for exactly an integer.

Can I use RegEx to reject a decimal point ??

Neil
citystate
Enthusiast
Enthusiast
Posts: 638
Joined: Sun Feb 12, 2006 10:06 pm

Re: Test that a string value has an integer format ???

Post by citystate »

absolutely

change the regex mask to be
^(-)?(\d)+$
there is no sig, only zuul (and the following disclaimer)

WARNING: may be talking out of his hat
Neil
Enthusiast
Enthusiast
Posts: 198
Joined: Wed Feb 29, 2012 8:04 am
Location: Melbourne, AUS

Re: Test that a string value has an integer format ???

Post by Neil »

citystate wrote:absolutely

change the regex mask to be
^(-)?(\d)+$
Sorry - what part of the expression is the "mask"

do I replace all this

Code: Select all

(0,"^(-)?(\d)+(\.)?(\d)*$")
with your line ??
citystate
Enthusiast
Enthusiast
Posts: 638
Joined: Sun Feb 12, 2006 10:06 pm

Re: Test that a string value has an integer format ???

Post by citystate »

replace this

Code: Select all

rx=CreateRegularExpression(0,"^(-)?(\d)+(\.)?(\d)*$")
with this

Code: Select all

rx=CreateRegularExpression(0,"^(-)?(\d)+$")

a breakdown of the regex ^(-)?(\d)+$:
^ start at the first character in the string
(-)? there can be either 0 or 1 negative signs, and then
(\d)+ there must be at least one numeric digit, and
$ we should be at the end of the string
there is no sig, only zuul (and the following disclaimer)

WARNING: may be talking out of his hat
Neil
Enthusiast
Enthusiast
Posts: 198
Joined: Wed Feb 29, 2012 8:04 am
Location: Melbourne, AUS

Re: Test that a string value has an integer format ???

Post by Neil »

citystate wrote:

Code: Select all

rx=CreateRegularExpression(0,"^(-)?(\d)+$")
a breakdown of the regex ^(-)?(\d)+$:
^ start at the first character in the string
(-)? there can be either 0 or 1 negative signs, and then
(\d)+ there must be at least one numeric digit, and
$ we should be at the end of the string
Hey that's fantastic (and thanks for the info on RegEx logic - it really is powerful).

Interesting example of "lateral" thinking!!

Instead of trying to determine if the string is an "integer" just check the allowable characters in the string.

Thanks,

Neil
User avatar
BasicallyPure
Enthusiast
Enthusiast
Posts: 539
Joined: Thu Mar 24, 2011 12:40 am
Location: Iowa, USA

Re: Test that a string value has an integer format ???

Post by BasicallyPure »

could it be this easy?

Code: Select all

Procedure IsInteger(text.s)
   ProcedureReturn (Bool(Not FindString(text,".")))
EndProcedure

Debug IsInteger("236523") ; 1
Debug IsInteger("-3232")  ; 1
Debug IsInteger("0.0")    ; 0
Debug IsInteger("-10.02") ; 0
Debug IsInteger("0.0a")   ; 0
BP
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
citystate
Enthusiast
Enthusiast
Posts: 638
Joined: Sun Feb 12, 2006 10:06 pm

Re: Test that a string value has an integer format ???

Post by citystate »

nah - with that procedure, IsInteger("abc") would be true
there is no sig, only zuul (and the following disclaimer)

WARNING: may be talking out of his hat
User avatar
BasicallyPure
Enthusiast
Enthusiast
Posts: 539
Joined: Thu Mar 24, 2011 12:40 am
Location: Iowa, USA

Re: Test that a string value has an integer format ???

Post by BasicallyPure »

try number 2.

Code: Select all

Procedure IsInteger(text.s)
   If (Bool(Not FindString(text,"."))) And (FindString(text, "0") Or ValF(text))
      ProcedureReturn #True
   Else
      ProcedureReturn #False
   EndIf
EndProcedure

Debug IsInteger("236523") ; 1
Debug IsInteger("-3232")  ; 1
Debug IsInteger("0.0")    ; 0
Debug IsInteger("-10.02") ; 0
Debug IsInteger("0.0a")   ; 0
Debug IsInteger("abc")    ; 0
Debug IsInteger("0")      ; 1
BP
BasicallyPure
Until you know everything you know nothing, all you have is what you believe.
Post Reply