April 02, 2017

AutoLISP: Creating a Zero-padded String

In one of the Autodesk Forums, someone had asked for a routine that would put each Polyline in a drawing file on a separate layer. That sounded like a fun challenge, and in the process of putting together a bare-bones solution, I had to decide how these new layers would be named. (I chose to let all of the other layer properties remain at their defaults.). Since I was using a while loop that included an integer-based counter variable to process each Polyline in turn, it seemed simple enough to use that integer value as part of layer name, to make the name unique for each Polyline. Being somewhat retentive, I wanted all the layer names for a given run of the routine to have the same number of characters in them, but there was no way to know up front how many Polylines there would be in any given file.

Once in a file, it is easy enough to determine the total number of polylines, and then to use the itoa AutoLISP function to convert that integer to a string and the strlen function to determine how many characters that largest number would have. To get all of the numeric strings to that same length, I wanted to use "zero padding"; that is, I wanted to add "0" characters to the front of shorter numeric strings to bring the total string length up to that of the largest number. The subroutine I wrote to do this turned out to be elegantly simple (or so I thought), so I decided to post the code here.

(defun ZEROPAD ( ;_ Arguments:
  inum   ; Number to be converted to zero-padded string [integer].
  ichar   ; Number of characters in zero-padded string [integer].
  / ;_ Local variables:
  ilen   ; Number of characters in integer to be converted [integer].
  snum   ; Integer to be converted as a string [string].
        ) ;_ End arguments and local variables.
  (setq snum (itoa inum)  ; String equivalent of integer to be converted.
 ilen (strlen snum)  ; Length of integer string.
  ) ;_ End setq.
  (while (< ilen ichar)   ; While integer string length is less than target length...
    (setq snum (strcat "0" snum) ; ...add "0" to front of string and...
   ilen (1+ ilen)  ; ...increment string length.
    ) ;_ End setq.
  ) ;_ End while.
  snum     ; Return final string.
) ;_ End ZEROPAD.

Somewhat less complicated than the Integer To String - Zero Padding node I created for Dynamo, but the same net result.

1 comment:

VladimĂ­r Michl said...

Or a less readable but much shorter and faster:

(defun ZEROPAD (n z)
(substr (strcat "00000000000000000000" (itoa n)) (+ (strlen (itoa n)) (- z) 21))
)