3

Common Lisp で「単一行」カウンター/プログレス バーを実装することに興味があります。派手なことは何もありません。次のようなものです。

=>

==>

===> ...など..

そして、最初からやり直してください。または、私が訪れたノードの数を数えることもできます。

しかし、これをすべて1行で行い、以前に印刷された文字をクリアしたい. たとえば、Python では次のようになります。

for i in range(0,1000):    
    print "\r",i,"   "

その後、これはカウントされますが、すべてを1行に保ち、特定の反復の前にその行に印刷されたすべてをクリアします。

私はLispに があることを知っていますが(format t "text" #\return)、それはうまくいかないようです。

誰も私がこれを行う方法を知っていますか? (私は周りを見回しましたが、何も見つからないようです)。

ありがとう、

アンドリュー

編集:

解決策を見つけました。を処理するには、ディレクティブを追加する必要があります (汎用の " ~A" が機能しました) #\return

(loop for i from 0 to 50000 do
        (format t "~A~A         " #\return i))

これは 50,000 までカウントされ、それが実行されるのを見ることができます。したがって、単一の出力行を再利用したい他の状況でも機能します。

4

2 に答える 2

1
 (defun show-progress (len)
  (format t "=")
  (dotimes
      (i len)
    (format t "="))
  (format t ">")
 )

この関数を実行すると、次の出力が表示されます。

CL-USER> (show-progress 10)
===========>
NIL
于 2012-10-16T03:10:34.510 に答える
0
(defun progress-bar ()
  (dotimes (i 100)
    (format t "~a>" (make-string i :initial-element #\=))
    (finish-output)
    (sleep 1)
    (dotimes (j (1+ i))
      (write-char #\Backspace))))

これは、同じ行に大きくなる「矢印」を印刷する方法です(等号文字を印刷した回数だけバックスペース文字を送信すると、それが消去されます)。

これは、コマンドとして解釈される可能性のある「特殊」文字を処理しないため、SLIME / SWANKの組み合わせでは機能しないことに注意してください。代わりに、曲折アクセント記号をエスケープします。これは、の束として出力されますが^H、これをターミナルで実行すると、次に矢印をクリーンアップして再印刷します。


そして、これはあなたがformat同じ文字を繰り返すことによって文字列をすることでそれをする方法です:

(defun progress-bar ()
  (dotimes (i 100)
    (format t (format nil "~~1,1,~d,'=:<>~~>" i))
    (finish-output)
    (sleep 1)
    (dotimes (j (1+ i))
      (write-char #\Backspace))))

より複雑な方法が好きな場合(実際には数文字短くなります!)。そして、まあ、それは元の文字列とまったく同じ数の文字列を作成します...おっと:)


残念ながら、文字をはっきりと繰り返す良いフォーマットディレクティブがわからないので、上記が最も簡単な方法のようですが、効率的に行う他の面白い方法があります。

(defun progress-bar ()
  (let ((arrow (make-array
                101
                :element-type 'character
                :initial-element #\>
                :fill-pointer 1)))
    (dotimes (i 100)
      (format t arrow)
      (setf (fill-pointer arrow) (+ i 2)
            (aref arrow i) #\=
            (aref arrow (1+ i)) #\>)
      (finish-output)
      (sleep 1)
      (dotimes (j (1+ i))
        (write-char #\Backspace)))))

(defun progress-bar ()
  (let (source)
    (dotimes (i 100)
      (format t "~{~c~}>" source)
      (push #\= source)
      (finish-output)
      (sleep 1)
      (dotimes (j (1+ i))
        (write-char #\Backspace)))))

例えば。

于 2012-10-16T13:41:32.880 に答える