2015-08-19 10 views
6

Szukałem poprzez formatowanie receptur, i nie mogę znaleźć dość co szukam ...CL Format przepis: Radzenie sobie z zera jako wartości

(format nil CONTROL-STRING day name num-apples)

Przypuśćmy, że don nie chce zmieniać argumentów w powyższym formularzu, tylko CONTROL-STRING.

day i num-apples będzie zawsze zerowy, ale name może być zerowy.

Kiedy name jest zerowa, chcę wyjście wyglądać

"Today is Monday. Hello, you have 3 apples."

ale kiedy name jest zdefiniowana, chcę wyglądać

"Today is Monday. Hello Adam, you have 3 apples."

So ciąg kontrola musi wyglądać na name, użyj go w przypadku non-nil, nie używać go do zera przypadku, ale zużywają go w obu przypadkach.

Może to można osiągnąć poprzez spożywanie nil i drukowanie go jako ""? Jeśli tak, nie wiem, jak to zrobić.

+1

Moja oryginalna wyszukiwarka nie była wystarczająco dobra. Myślę, że to ma moją odpowiedź. http://stackoverflow.com/questions/5729032/lisp-format-directive-that-interprets-nil-argument-to-empty-string-instead-of-n?rq=1 –

Odpowiedz

9

Pytanie, z którym łączysz się, Lisp format directive that interprets nil argument to empty string instead of "NIL", zawiera odpowiedź, która pokazuje, jak możesz to zrobić, ale nie cytuje żadnej dokumentacji. Ponieważ generujesz tekst w języku angielskim, istnieje również kilka innych opcji, które warto rozważyć.

Po pierwsze, z ~ @ [konsekwentna ~], można przetwarzać konsekwencji dyrektywy z formatu tylko w przypadku, gdy argument jest non-zero, a argument ~ @ [ nie jest spożywana , więc nadal jest dostępny. W ogóle, 22.3.7.2 Tilde Left-Bracket: Conditional Expression opisuje wiele opcji, ale o ~ @ [ mówi:

~ @ [konsekwentna ~] testuje argument. Jeśli jest to prawdą, argument nie jest używany przez ~ [polecenie, ale pozostaje w następnej być przetwarzane i w konsekwencji jeden punkt jest przetwarzany. Jeśli argument arg jest fałsz, argument zostanie wykorzystany, a klauzula nie zostanie przetworzona. Klauzula dlatego powinien normalnie używać dokładnie jeden argument, a może oczekiwać, że będzie non-zero.

Można to wykorzystać w następujący sposób:

(defun test (day name n-apples) 
    (format nil "Today is ~a. [email protected][ ~a~], you have ~a apples." 
      day name n-apples)) 

CL-USER> (test 'monday 'adam 2) 
"Today is MONDAY. Hello ADAM, you have 2 apples." 
CL-USER> (test 'tuesday nil 42) 
"Today is TUESDAY. Hello, you have 42 apples." 

Aby to jeszcze bardziej wytrzymałe, należy rozważyć użycie ~p for pluralization, aby uzyskać "1 jabłko" i " 3 jabłko s ".

(defun test (day name n-apples) 
    (format nil "Today is ~a. [email protected][ ~a~], you have ~a apple~:P." 
      day name n-apples)) 

CL-USER> (test 'monday 'john 2) 
"Today is MONDAY. Hello JOHN, you have 2 apples." 
CL-USER> (test 'tuesday 'john 1) 
"Today is TUESDAY. Hello JOHN, you have 1 apple." 
CL-USER> (test 'wednesday nil 0) 
"Today is WEDNESDAY. Hello, you have 0 apples." 

Wreszcie, ponieważ jesteś generowania tekstu, można docenić niektórych przypadkach normalizacji (np wydrukować odpowiednie rzeczowniki z początkowymi literami) i pisanie liczb w tekście:

(defun test (day name n-apples) 
    (format nil "Today is ~:(~a~). [email protected][ ~:(~a~)~], you have ~r apple~:P." 
      day name n-apples)) 
CL-USER> (list 
      (test 'monday 'adam 4) 
      (test 'tuesday 'john 1) 
      (test 'wednesday 'mary\ sue 42) 
      (test 'thursday 'jim-bob 0)) 
("Today is Monday. Hello Adam, you have four apples." 
"Today is Tuesday. Hello John, you have one apple." 
"Today is Wednesday. Hello Mary Sue, you have forty-two apples." 
"Today is Thursday. Hello Jim-Bob, you have zero apples.") 
Powiązane problemy