How to initialize a string with a fill pointer in Common Lisp?
Asked Answered
O

3

5

I want to use formatted output in a loop to generate a string. Manual says it can be easily done by giving format function a string with a fill pointer as a destination. Unfortunately, it is not transparent from the manual how to initialize this string in the first place.

I tried (string "") and (format nil "") with no luck.

(make-array 0 :element-type 'character :fill-pointer 0) did work for me, but it just doesn't feel right.

What is the proper way to initialize a string with a fill pointer?

Outstretch answered 7/8, 2013 at 7:47 Comment(0)
S
5

(make-array 0 :element-type 'character :fill-pointer 0) is the canonical way (well, it's quite possible to use an initial non-zero length and use :initial-contents with a string value). It's also possible to specify the fil-pointer value as t, that will set the fill-pointer at the end of the string.

Saum answered 7/8, 2013 at 8:21 Comment(0)
P
9
(make-array estimated-size-of-final-string
            :element-type 'character :fill-pointer 0)

(with :adjustable t too if the estimate is inaccurate) is one way; for accumulating output to produce a string it may be more idiomatic to use with-output-to-string:

(with-output-to-string (stream)
  (loop repeat 8 do (format stream "~v,,,'-@A~%" (random 80) #\x)))

=>

"----------------------------------x
--------x
--------------------------------------x
----------------------------------------------------------------x
--------------x
-----------------------------------------x
---------------------------------------------------x
-----------------------------------------------------------x
"
Proviso answered 7/8, 2013 at 11:40 Comment(0)
A
7

Using FORMAT to a string with a fill pointer is a very rarely used functionality.

CL-USER 125 > (let ((s (make-array 0
                                   :element-type 'character
                                   :adjustable t
                                   :fill-pointer t)))
                (format s  "Hello, ~a!" 'bill)
                s)
"Hello, BILL!"

CL-USER 126 > (describe *)

"Hello, BILL!" is an (ARRAY CHARACTER (12))
FILL-POINTER      12
0                 #\H
1                 #\e
2                 #\l
3                 #\l
4                 #\o
5                 #\,
6                 #\Space
7                 #\B
8                 #\I
9                 #\L
10                #\L
11                #\!
Accustomed answered 7/8, 2013 at 12:25 Comment(2)
That is very cool, I didn't know that format accepted something else than a stream. Thanks!Egestion
My experience was quite the opposite: I read that format can write to a string but it was unclear to me how exactly; all examples then wrote to t or nil and only after quite some searching this post has solved it. Thanks!Egor
S
5

(make-array 0 :element-type 'character :fill-pointer 0) is the canonical way (well, it's quite possible to use an initial non-zero length and use :initial-contents with a string value). It's also possible to specify the fil-pointer value as t, that will set the fill-pointer at the end of the string.

Saum answered 7/8, 2013 at 8:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.