[plt-scheme] formatting integer in string

From: Chris Uzdavinis (chris at atdesk.com)
Date: Sat Aug 17 03:05:01 EDT 2002

I'm unhappy with the solution I've found to a simple (in C at least)
problem.  

I need write a 1-byte value (guaranteed range 0-256) into a 3-digit
string, with leading zeros for padding if necessary.

The closest function I've found was number->string, but there is no
way to specify a format, and it omits the leading zeros.  I was hoping
to find some numerical format specifiers for the fprintf function in
the mzscheme language reference (v201) but didn't see anything that
looked useful.

Here is the solution I came up with, and I'm embarassed by it.  :)

;; num -> str
;; num guaranteed in range 0-256
(define (num->padded-string num)
  (if (> (quotient num 100) 0)
      (number->string num)
      (if (> (quotient num 10) 0)
          (string-append "0" (number->string num))
          (string-append "00" (number->string num)))))
 

Is there an easier way?  Also, any suggestions for a better function
name are welcome....

While playing around I generalized the function to take a width,
recursively setting each byte of the string.  

(define (num->padded-string num width)
  (define ascii-zero (char->integer #\0))
  (let ([output (make-string width)])
    (let loop ([idx 0]
               [num num])
      (cond [(= idx width) output]
            [else (string-set! output 
                               (- width idx 1) 
                               (integer->char (+ ascii-zero 
                                                 (modulo num 10))))
                  (loop (add1 idx) (quotient num 10))]))))


But this is absolutely crazy to have to write.  I'd prefer to do
something like this to a string-port:

(fprintf port "%0.*d" width num)

I'd have to be stupid to think nobody using Scheme ever formats
numbers into strings, but shoot me if I can figure out how to do it.
:)

If I'm stuck with my solutions, I guess that's that, but I'd really
appreaciate any advice on doing this better.

Thanks!!

-- 
Chris




Posted on the users mailing list.