Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I format a single backslash in common lisp?

I'm currently trying to get an output of ... \hline in GNU Common lisp 2.49, but I can't get the format to work. This is what I've tried so far to get a single backslash:

(format nil "\ ") => " "
(format nil "\\ ") => "\\ "
(format nil "\\\ ") => "\\ "

I thought that the double backslash would make it work, why isn't the backslash escaping just the other backslash?

like image 619
iHowell Avatar asked Oct 12 '18 15:10

iHowell


People also ask

What is the use of format in Lisp?

Format (Common Lisp) Format is a function in Common Lisp that can produce formatted text using a format string similar to the printf format string.

How do you make a full Slash on a keyboard?

Looks like Dennis was first to probably the easiest answer to execute, the double-backtick approach. On windows systems, you can often generate the full-width slash by holding down the Alt key and pressing + (numeric keypad), F F 3 C (lower-case is fine).

How do I make a full-width slash?

On windows systems, you can often generate the full-width slash by holding down the Alt key and pressing + (numeric keypad), F F 3 C (lower-case is fine). You must log in to answer this question. Not the answer you're looking for?


2 Answers

See for example:

CL-USER> (write "\\" :escape nil)
\
"\\"

Here above, the first backslash is your string, printed without escaping backslashes. The returned value is the string, printed by the REPL with the standard io syntax (http://clhs.lisp.se/Body/m_w_std_.htm), which escapes strings.

So, your string contains a single backslash, but is printed in such a way that it can be read back, hence the need to escape the backslash in the output string.

Note also that calling format with NIL and a single string returns the same string.

You can inspect your strings, for example by mapping each character to its name:

(loop
   for input in '("\ " 
                  "\\ "
                  "\\\ ")
   collect (list :input input
                 :characters (map 'list #'char-name input)))

This gives:

((:INPUT " " :CHARACTERS ("Space"))
 (:INPUT "\\ " :CHARACTERS ("REVERSE_SOLIDUS" "Space"))
 (:INPUT "\\ " :CHARACTERS ("REVERSE_SOLIDUS" "Space")))

Or, simply use inspect:

CL-USER> (inspect "\\hline")

The object is a VECTOR of length 6.
0. #\\
1. #\h
2. #\l
3. #\i
4. #\n
5. #\e
like image 142
coredump Avatar answered Nov 17 '22 09:11

coredump


Note the difference between creating a string and actually doing output to a stream:

CL-USER 69 > (format nil "\\ ")
"\\ "                               ; result

CL-USER 70 > (format t "\\ ")
\                                   ; output
NIL                                 ; result

CL-USER 71 > (format *standard-output* "\\ ")
\                                   ; output
NIL                                 ; result
like image 29
Rainer Joswig Avatar answered Nov 17 '22 09:11

Rainer Joswig