Snippet stringType

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
stringType
Created by Darthfett

Description:
A small collection of functions that can be used to determine a string's type, such as if it is numerical, a metacharacter, etc.

Requirements:
N/A

The rest of the documentation can be found in the system code, below:

JASS:
library stringType
/*
__________________________________________________________________________________

        stringType library, created by Darthfett - version 1.2
        http://www.thehelper.net/forums/showthread.php?t=143592
        
                                Requirements
                                
-vJass compiler (such as JASSHelper)
    -If you remove the library and multi-line comment(s), you can make this JASS compatable.

                                Documentation
                                
-All functions are standalone.  Feel free to copy an individual function.

-Credit for this library is not necessary.  Feel free to use it in your map.
If you feel obligated to credit me, I won't object.  I only ask that you do 
not simply copy and paste the library as your own.

                                    API

function IsInt takes string s returns boolean
    returns whether a string is a numeric integer.
    (Not necessarily within integer bounds)
    
function IsReal takes string s returns boolean
    returns whether a string a numeric real.
    (Not necessarily within real bounds)
    
function IsLetter takes string s returns boolean
    returns whether the specified character is a letter (a-z,A-Z).
    
function IsLetters takes string s returns boolean
    returns whether the specified string contains only letters (a-z,A-Z).
    
function IsMeta takes string s returns boolean
    returns whether the specified character is a metacharacter (!@#$%^...)
    
function IsMetas takes string s returns boolean
    returns whether the specified string contains only metacharacters (!@#$%...)
__________________________________________________________________________________
*/

function IsInt takes string s returns boolean
    local integer i = 0
    local integer j
    local string c
    local integer len
    local integer sublen
    if s == "" or s == null or s == "-" or s == "+" then
        return false
    endif
    if I2S(S2I(s)) == s then
        return true
    endif
    set len = StringLength(s)
    loop
        set sublen = IMinBJ(i+8,len)
        exitwhen i == len
        set c = SubString(s,i,sublen)
        if I2S(S2I(c)) != c then
            set j = sublen
            loop
                exitwhen j == i
                set c = SubString(s,j-1,j)
                if I2S(S2I(c)) != c then
                    if (c == "+" or c == "-") and j == 1 then
                        //pass
                    else
                        return false
                    endif
                endif
                set j = j - 1
            endloop
        endif
        set i = sublen
    endloop
    return true
endfunction

function IsReal takes string s returns boolean
    local integer i = 0
    local integer j
    local integer k = 0
    local string c
    local integer len
    local integer sublen
    if s == "" or s == null or s == "-" or s == "+" then
        return false
    endif
    if R2S(S2R(s)) == s then
        return true
    endif
    set len = StringLength(s)
    loop
        set sublen = IMinBJ(i+8,len)
        exitwhen i == len
        set c = SubString(s,i,sublen)
        if I2S(S2I(c)) != c then
            if R2S(S2R(c)) == c then
                set k = k + 1
                if k > 1 then
                    return false
                endif
            else
                set j = sublen
                loop
                    exitwhen j == i
                    set c = SubString(s,j-1,j)
                    if I2S(S2I(c)) != c then
                        if c == "." then
                            set k = k + 1
                            if k > 1 then
                                return false
                            endif
                        elseif (c == "+" or c == "-") and j == 1 then
                            //pass
                        else
                            return false
                        endif
                    endif
                    set j = j - 1
                endloop
            endif
        endif
        set i = sublen
    endloop
    return true
endfunction

function IsLetter takes string s returns boolean
    return StringCase(s,true) != StringCase(s,false) and StringLength(s) == 1
endfunction

function IsLetters takes string s returns boolean
    local integer i = 0
    local string str
    loop
        set str = SubString(s, i, i + 1)
        exitwhen str == ""
        if StringCase(s,true) == StringCase(s,false) then
            return false
        endif
        set i = i + 1
    endloop
    return true
endfunction

function IsMeta takes string s returns boolean
    return I2S(S2I(s)) != s and StringCase(s,true) == StringCase(s,false) and StringLength(s) == 1
endfunction

function IsMetas takes string s returns boolean
    local integer i = 0
    local string str
    if StringCase(s,true) != StringCase(s,false) then
        return false
    endif
    loop
        set str = SubString(s, i, i + 1)
        exitwhen str == ""
        if I2S(S2I(str)) == str then
            return false
        endif
        set i = i + 1
    endloop
    return true
endfunction

endlibrary
 

Steel

Software Engineer
Reaction score
109
These operations are a misnomer, you cannot determine if a string is a type, you can only determine if a character is a type.
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
These operations are a misnomer, you cannot determine if a string is a type, you can only determine if a character is a type.

Why do you say that?

Except for the int/numerical functions, it checks the string character by character. If the string is contained entirely of metacharacters, it isMeta. If it is contained entirely of alphabetical characters, it isAlpha.
 

Azlier

Old World Ghost
Reaction score
461
@TriggerHappy
JASS:
if IsNumeric("000") then
    call BJDebugMsg("All's good.")
else
    call BJDebugMsg("Hold on...")
endif
 
Reaction score
341
Erm, fine.
At the very least he should check [ljass]S2I(str) != 0 [/ljass] before doing all those calculations.
 

Azlier

Old World Ghost
Reaction score
461
The optimal method would be to check [lJASS]I2S(S2I(s)) == s[/lJASS]. If not, then check if the string is composed entirely of zeroes.
 

tooltiperror

Super Moderator
Reaction score
231
Str == vJass shortage of 'string'?
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
Update Version 1.1

@TriggerHappy
JASS:
if IsNumeric("000") then
    call BJDebugMsg("All's good.")
else
    call BJDebugMsg("Hold on...")
endif

Good point, mine would also have problems with that.

Erm, fine.
At the very least he should check [ljass]S2I(str) != 0 [/ljass] before doing all those calculations.

That would make no sense, as S2I("!%GJAWasdfj") will also return 0.

The optimal method would be to check [lJASS]I2S(S2I(s)) == s[/lJASS]. If not, then check if the string is composed entirely of zeroes.

What if the string is 0175971? If I then compare 1 and 0, the function would return false.

What about "IsReal"?

Good point.

I've updated the library with a new IsReal function, and I've merged the IsInt and IsNumeric functions so that the problem with 0s is fixed.
 

Azlier

Old World Ghost
Reaction score
461
Last I checked 0# is an 8-bit number. Is 065343 even valid?
 

Deaod

Member
Reaction score
6
Last I checked 0# is an 8-bit number. Is 065343 even valid?
Last i checked, a leading 0 indicates base 8 numbers only in code. I dont think S2I recognizes that.

Yes, 065343 is a valid base 8 number. 0175971 is not.
 

Lyerae

I keep popping up on this site from time to time.
Reaction score
105
I believe if it starts with an 0, it's octal, right?
I'm not exactly sure how JASS processes integers though.
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
Because i'm doing a string calculator i need these kind of functions, however i've found that your IsInt function fails with valid syntaxes such as "+66","002","-0".

So i've made my own, i think that is well commented but if you don't understand something you can still ask me :)

JASS:
function IsInt takes string whichString returns boolean
    local integer i
    local string s
    
    if I2S(S2I(whichString)) == whichString then // it's definitely an integer
        return true
    elseif StringLength(whichString) <= 1 then // there is no way it's a valid integer
        return false
    endif
    set s = SubStringBJ(whichString,1,1) 
    if not(s == "+" or s == "0" or s == "-") then // invalid integer because it's the only reason why a valid integer could be different when converted with S2I(I2S) , s == "-" is needed because of "-0"
        return false
    endif
    // now cheking for 0
    set i = 1
    loop
    set i = i+1
    set s = SubStringBJ(whichString,i,i) 
    // check the string left to right while we found a "0" character
    exitwhen s == "" or s == null
        if S2I(s) == 0 then // it could be a 0, and since we take only one character it can't be < 0 
            if s != "0" then // it's not a 0, so it's an invalid character
                return false // invalid integr
            endif
        // fatally s > 0 here, time to check the left part of the string    
        elseif not(S2I(SubStringBJ(whichString,i,StringLength(whichString))) == IAbsBJ(S2I(whichString))) then
            return false // invalid integer
        else
            exitwhen true // this check is valid but we need to check the right part of the string now
        endif
    endloop
    
    // checking the right part of the string (if it's not already done)
    loop
    set i = i+1
    set s = SubStringBJ(whichString,i,i)
    exitwhen s == "" or s == null
        if S2I(s) == 0 and s != "0" then   // invalid integer
            return false
        endif
    endloop
    
    return true
endfunction


Notes :

You can inline SubStringBJ if you don't want lame comments about BJ usage.
I simply like the BJ because it makes more sense for me, or in other words i make less mistakes when i need to cut a string.
It is not like a such function would be used each 0.001 s anyway ...
And wc3mapoptimizer is your friend, more, he even doesn't inline constant handles (private joke) !

It's kinda the same for "IAbsBJ".

EDIT :
It will also fail with IsReal for explicit negatives and positives reals, like "+5.1234" "-9.1234"
And finally IsMeta and IsLetter should care about the StringLength which strictly must be == 1.
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
Thanks for pointing out a few bugs in the IsInt function, I missed them when I optimized the inner loop. This was causing problems with integers longer than 8, and integers that started with 0's.

I've fixed the bug, and also updated the system to support the use of signed ints/reals ('+' and '-', because '+5' has the same logical value as '5' which is returned by [ljass]S2I('+5')[/ljass]).

I've been able to retain most of the original optimizations I made, as I simply made the functions cut off any leading '+' or '-', and the IsInt function will no longer SubString slice from any area larger than the length, using the [ljass]IMinBJ[/ljass] function (What's this, a useful BJ function?!).

It is not like a such function would be used each 0.001 s anyway ...

Troll-Brain, thanks for creating your own, but while this is true, I believe that in a submitted system, I should go out of the way to make it as lightweight as can be. I have a nice optimization for longer strings (it will check the string in slices of 8 chars before resorting to single characters (and only checks each of those 8 chars, going back to slices of 8 if that slice checks out okay)).

And finally IsMeta and IsLetter should care about the StringLength which strictly must be == 1.

I thought about doing this, but when using < 8 character length strings, it does avoid the bloat around using the loop for the IsMetas and IsLetters functions.

Anyone else have any opinions about this? Technically if it's > 1 character, it isn't a character.
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
Totally by accident I've found a new bug now, "--X" returns true when X > 0, same with "+-X".

JASS:
if SubString(s,0,1) == &quot;-&quot; or SubString(s,0,1) == &quot;+&quot; then
   set s = SubString(s,1,StringLength(s))
endif

You don't need to redefine the string, just to skip the first character of it (i==1).
The reason of the bug is i suppose the order of the if I2S(S2I(s)) == s should be done the first, or after the "null", or "" check (didn't tested)

I should go out of the way to make it as lightweight as can be. I have a nice optimization for longer strings (it will check the string in slices of 8 chars before resorting to single characters (and only checks each of those 8 chars, going back to slices of 8 if that slice checks out okay)).
Sure, but i think the difference between using SubStringBJ and SubString is totally negligible comparing the use of SubString by itself though.
I mean cutting the string would be much more slower than this difference between the BJ and the native.

I think that 'sublen' is unneeded, i mean you can simply use 'i' instead.
Also i don't like this idea of cutting string, why not simply the whole string ?

I thought about doing this, but when using < 8 character length strings, it does avoid the bloat around using the loop for the IsMetas and IsLetters functions.

Anyone else have any opinions about this? Technically if it's > 1 character, it isn't a character.

If you consider a string which have a length > 1 , that makes IsLetter as a no sense because of the existent of IsLetters
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top