x_strex()... a variation on str()

Share your advanced PureBasic knowledge/code with the community.
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6172
Joined: Sat May 17, 2003 11:31 am
Contact:

x_strex()... a variation on str()

Post by blueznl »

Code updated for 5.20+

Code: Select all

Procedure.s x_strex(var.l,format.s)
  Protected s.s, fl.l, sl.l, *f.BYTE, *s.BYTE, p.l, sb.l
  ;
  ; *** format integer to string
  ;
  ; in:  var.l    - int varar
  ;      f.s    - format
  ; out: .s    - string
  ;
  ; convarert int varar to string using a pattern
  ;
  ; pattern elements:
  ;
  ; '#' - number or leading zero
  ; ' ' - space, number or (when there's no '+' or '-' used in the format) sign
  ; '+' - positivare or negativare indicator
  ; '.' - decimal sign
  ;
  ; examples:
  ;
  ; x_strex( 1234,     "###") =     "***"
  ; x_strex( 1234,   "##.##") =   "12.34"
  ; x_strex(-1234,   "##.##") =   "*****"
  ; x_strex(    1,  ".#####") =  ".00001"
  ; x_strex(   -1, "+   .##") = "-   .01"
  ;
  fl = Len(format)
  s = Str(var)
  sl = Len(s)
  ;
  *f.BYTE = @format+fl                               ; using two pointers and two counters
  *s.BYTE = @s+sl
  ;
  If PeekB(@format) = '+'                            ; remember is there is a sign in a fixed place
    p = 2
  ElseIf PeekB(@format) = '-'
    p = 1
  EndIf
  ;
  While fl > 0
    *f-1
    fl-1
    If *f\b = '.'                               ; skip a dot if we pass one
    Else
      sl-1
      If sl >= 0
        *s-1
        sb = *s\b                               ; sb contains the digit, AND is used as a flag
      EndIf
      Select *f\b
        Case '-'                                ; ah, a sign in a fixed place
          If sb = '-'
            sb = -1                             ; if sb = -1 we'vare managed to store the sign
          Else
            *f\b = ' '
          EndIf
        Case '+'                                ; same thing for the +
          If sb = '-'
            *f\b = sb
            sb = -1
          EndIf
        Case '#'                                ; if we havare data that is not a sign we're gonna fill it in
          If sb = '-' Or sl < 0
            *f\b = '0'                          ; otherwise it's going to be a zero
          Else
            *f\b = *s\b
          EndIf
        Case ' '                                ; if there is no fixed spot for a sign we'll store the minus
          If sb = '-'                           ; immediately on the first space we encounter
            If p = 0
              *f\b = '-'
              sb = -1
            EndIf
          ElseIf sb <> -1 And sl >= 0           ; otherwise we'll just gonna fil it in
            *f\b = *s\b
          EndIf
      EndSelect
    EndIf
  Wend
  ;
  If sb = '-' Or sl > 0                         ; if the sign wasn't stored or there was some data left
    format = LSet("",Len(format),"*")           ; we'll put in some stars to indicate ovarerflow
  EndIf
  ;
  ProcedureReturn format
EndProcedure
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB - upgrade incoming...)
( The path to enlightenment and the PureBasic Survival Guide right here... )
fweil
Enthusiast
Enthusiast
Posts: 725
Joined: Thu Apr 22, 2004 5:56 pm
Location: France
Contact:

Post by fweil »

blueznl,

My contribution ...

Not for starting a contest but, I thought a way to process faster strings when parsing characters.

Code: Select all

Structure StringBytes
  Bytes.b[64000]
EndStructure

Procedure.s x_strex6(n.l, format.s)
  *MyString.StringBytes = @format
  ipt = Len(format) - 1
  If n < 0
      Sign = #TRUE
      n = -n
  EndIf
  Repeat
    If n <> 0
        d = n % 10
        n = (n - d) / 10
        If *MyString\Bytes[ipt]  = '#'
            *MyString\Bytes[ipt] = d + 48
          Else
            ipt - 1
            *MyString\Bytes[ipt] = d + 48
        EndIf
      Else
        If Sign
            *MyString\Bytes[ipt] = '-'
            Sign = #FALSE
          Else
            *MyString\Bytes[ipt] = ' '
        EndIf
    EndIf
    ipt - 1
  Until ipt < 0
  ProcedureReturn format
EndProcedure

Debug x_strex6(-123456789, "###.###.###.###")
This way makes string manipulation easy and by declaring such a 'StringBytes' structure is available all over the program you code. By dimensioning Bytes.b to 64K corresponds to all available strings in PB. Also you may change this value for using longer strings if you change the PB_STRINGBASE string allocation size.

KRgrds
My avatar is a small copy of the 4x1.8m image I created and exposed at 'Le salon international du meuble à Paris' january 2004 in Matt Sindall's 'Shades' designers exhibition. The original laminated print was designed using a 150 dpi printout.
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6172
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

hadn't thought about using an index...

hey, the more we all see, the more we all learn :-)

i don't mind, i just hope that any snippets posted can be useful to someone

i needed a str() function with fixed length, then decided to enhance it a little to be able to line up some financial tables as:

Code: Select all

    1234
 -      1
 -    222
    ----
    1011
something like that just migth come in handy one day :-)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB - upgrade incoming...)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Post Reply