Page 1 of 1

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

Posted: Sat Apr 24, 2004 8:45 pm
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

Posted: Tue Apr 27, 2004 6:37 pm
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

Posted: Tue Apr 27, 2004 7:38 pm
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 :-)