如何用填充指针清除字符串?

147*_*7pm 3 common-lisp

这是我在Hyperspec上看到的一个例子:

(setq fstr (make-array '(0) :element-type 'base-char
                             :fill-pointer 0 :adjustable t))
(with-output-to-string (s fstr)
    (format s "here's some output"))
Run Code Online (Sandbox Code Playgroud)

因此,然后fstr持有here's some output问:你怎么可以做一个简单的清除/重置fstr你想重新开始,把东西在它新的情况,即没有串联多到了吗?或者我只需要重做fstr正在设置的顶级表达式?

Rai*_*wig 8

设置填充指针:

CL-USER 3 > (setq fstr (make-array '(0) :element-type 'base-char
                                   :fill-pointer 0 :adjustable t))
""

CL-USER 4 > (with-output-to-string (s fstr)
              (format s "here's some output"))
NIL

CL-USER 5 > fstr
"here's some output"

CL-USER 6 > (setf (fill-pointer fstr) 0)
0

CL-USER 7 > fstr
""

CL-USER 8 > (with-output-to-string (s fstr)
              (format s "here's some more output"))
NIL

CL-USER 9 > fstr
"here's some more output"
Run Code Online (Sandbox Code Playgroud)

您也可以调用adjust-array实际更改数组大小.

CL-USER 16 > (setf (fill-pointer fstr) 0)
0

CL-USER 17 > (adjust-array fstr 0)
""
Run Code Online (Sandbox Code Playgroud)


Jos*_*lor 6

这里有两个相互作用的正交概念.第一个是矢量(字符串,一维数组等)可以有一个填充指针:

填写指针 ñ.(向量)一个与向量相关联的整数,该向量表示没有元素处于活动状态的索引.(填充指针是一个非负整数,不大于向量中元素的总数.并非所有向量都有填充指针.)

当你正在寻找一个字符串,填充指针本质上是字符串的长度,但可以让底层阵列实际上包含更多的数据(仍然可以访问 ;根据不同的应用,这可能是重要的).

然后,有很多方法可以使用填充指针操作向量的内容.对于字符串,有一个有用的字符串,由输出到字符串提供,它创建一个字符输出,将字符输出发送到字符串.

with-output-to-string创建一个字符输出流,执行一系列可以将结果发送到此流的操作,然后关闭该流.

因此,您可以使用(setf fill-pointer) "重置"您的字符串,并且您可以使用with-output-to-string添加内容,以及其他方式:

(let ((str (make-array '(0)
                       :element-type 'base-char
                       :adjustable t
                       :fill-pointer 0)))

  ;; Temporarily create a character output stream that directs its
  ;; output to the underlying string that we created, and write "hello
  ;; world!"  to it.
  (with-output-to-string (s str)
    (format s "hello world!"))

  ;; prints "hello world", sets the FILL-POINTER back to 0, and then
  ;; prints "".
  (print str)
  (setf (fill-pointer str) 0)
  (print str)

  ;; But note that the underlying array
  ;; and the content that you put into
  ;; it are still available.  While LENGTH
  ;; returns 0, ARRAY-TOTAL-SIZE reports
  ;; 12, and you can still just AREF to
  ;; get the old content.
  (print (length str))                  ;=> 0
  (print (array-total-size str))        ;=> 12
  (print (aref str 6))                  ;=> #\w

  ;; update content using vector push extend, and print "abcde".
  (vector-push-extend #\a str)
  (vector-push-extend #\b str)
  (vector-push-extend #\c str)
  (vector-push-extend #\d str)
  (vector-push-extend #\e str)
  (print str)                           ;=> "abcde"

  ;; Or set the fill pointer manually, possibly setting content in the
  ;; array before or after.  Note that you can (SETF AREF) elements in
  ;; the vector that aren't in the active portion.  First, we confirm
  ;; that the fill pointer is at 5, then set an element at 8 (past the
  ;; fill pointer), then set the fill pointer to 10, and set an
  ;; element at 6 (before the fill pointer).  All these changes affect
  ;; the vector contents.
  (print (fill-pointer str))            ;=> 5
  (setf (aref str 8) #\X)
  (setf (fill-pointer str) 10)
  (setf (aref str 6) #\Y)
  (print str)                           ;=> "abcde YoXl"

  )
Run Code Online (Sandbox Code Playgroud)