Lisp formatta un personaggio un numero di volte

Sto cercando un modo per emettere un personaggio un numero di volte usando il formato. È ansible? Qualcuno può compilare i _?_ , In modo che l’esempio funzioni?

 (let ((n 3)) (format nil "_?_" _?_ #\* _?_ )) 

dovrebbe tornare

 => "***" 

È bello vedere così tante soluzioni: ~ A, ~

Il costrutto ~ @ {iteration fornisce una soluzione concisa:

 (format nil "[email protected]{~A~:*~}" 3 #\*) 

Se si utilizza la direttiva ~A , è ansible ottenere questo esattamente nella forma che hai suggerito, cioè,

 (let ((n 3)) (format nil "_?_" _?_ #\* _?_ )) 

con tre argomenti di formato. Tuttavia, se si utilizza ~< , è ansible farlo con solo due argomenti di formato. Se non hai bisogno di questa stringa all'interno di qualche altra stringa che è già generata dal format , puoi anche creare la stringa usando la make-string .

Utilizzo di Tilde A (~ A)

È ansible stampare il carattere e specificare una larghezza minima e lo stesso carattere del carattere di riempimento. Ad esempio, usando ~v,,,vA e due argomenti, è ansible assicurarsi che venga stampato un certo numero di caratteri e quale sia il carattere di riempimento.

 CL-USER> (let ((n 3)) (format nil "~v,,,vA" n ; number of characters that must be printed #\* ; character to use as padding #\*)) ; character to print with ~A "***" CL-USER> (let ((n 3)) (format nil "~v,,,vA" n #\* #\*)) "***" CL-USER> (let ((n 10)) (format nil "~v,,,vA" n #\* #\*)) "**********" 

Questo utilizza la forma completa di ~A :

~ mincol, colinc, minpad, padcharA è la forma completa di ~ A, che consente il controllo del padding. La stringa è riempita a destra (o a sinistra se si usa il modificatore @) con almeno copie minpad di padchar; i caratteri di riempimento vengono quindi inseriti caratteri di colore alla volta fino a quando la larghezza totale è almeno mincol. Le impostazioni predefinite sono 0 per mincol e minpad, 1 per colinc e il carattere di spazio per padchar.

così come v :

Al posto di un parametro prefisso per una direttiva, è ansible utilizzare V (o v). In questo caso, il formato accetta un argomento da args come parametro alla direttiva. L'argomento dovrebbe essere un numero intero o un carattere. Se l'arg utilizzato da un parametro V è nullo, l'effetto è come se il parametro fosse stato omesso. # può essere usato al posto di un parametro prefisso; rappresenta il numero di argomenti rimanenti da elaborare. Se utilizzato all'interno di un formato ricorsivo, nel contesto di ~? o ~ {, il parametro # prefix rappresenta il numero di argomenti di formato rimanenti all'interno della chiamata ricorsiva.

Usare Tilde meno di (~ <)

C'è anche una direttiva di formato meno comunemente usata, tilde less than, usata per la giustificazione. prende una stringa di formato e crea s

~ Mincol, colinc, minpad, padchar

Questo giustifica il testo prodotto dall'elaborazione di str all'interno di un campo di almeno mincol colonne di larghezza. str può essere diviso in segmenti con ~ ;, nel qual caso la spaziatura è equamente divisa tra i segmenti del testo.

Possiamo (ab) usarlo passando una stringa di formato vuota e specificando semplicemente la larghezza e il carattere di riempimento:

 CL-USER> (let ((n 3)) (format nil "~v,,,v<~>" n ; width #\*)) ; padding character "***" CL-USER> (let ((n 5)) (format nil "~v,,,v<~>" n #\*)) "*****" 

Basta fare una stringa

Ovviamente, a meno che non si abbia bisogno di questa stringa speciale all'interno di qualche altra stringa che si sta già formattando, si dovrebbe fare quello che suggeriva wvxvw, e basta usare la make-string :

 (make-string 3 :initial-element #\*) 

Altre alternative

format è molto flessibile e, come questa e altre risposte stanno sottolineando, ci sono molti modi per farlo. Ho cercato di attenermi a quelli che dovrebbero fare questo in un passaggio e non fare iterazioni esplicite, ma questo può essere fatto anche con le iterazioni del format , come hanno sottolineato Lars Brinkhoff e wvxvw .

 (format nil "~a~:*~a~:*~a~:*" #\*) "***" 

O elaborando un po ‘la risposta di Joshua Taylor:

 (format nil "~v{~a~:*~}" 3 '(#\*)) 

Sarebbe un modo per farlo. Non essere confuso dagli asterischi nella direttiva format , sono caratteri di controllo, non caratteri stampati.


In termini di efficienza, tuttavia, questo:

 (make-string 3 :initial-element #\*) 

sarebbe un modo preferito per ottenere lo stesso effetto.

Come la risposta di Lars, ma scriviamo il carattere wih ~C , invece di usare la stampante con ~A :

 (format nil "[email protected]{~C~:*~}" 3 #\*) 

Scrivere un personaggio con qualcosa come write-char è un’operazione più semplice della stampa di un object Lisp. La stampante ha un sacco di contesto da osservare e deve trovare il modo giusto per stampare l’object. OTOH, qualcosa come WRITE-CHAR scrive solo un singolo carattere in un stream.