Solving Advent of Code 2015 task 8 part2 I encountered the problem to have to distinguish in a string the occurrence of "\x27" from plain "x27". But I don't see a way how I can do it. Because
(length "\x27") ;; is 3
(length "x27") ;; is also 3
(subseq "\x27" 0 1) ;; is "x"
(subseq "x27" 0 1) ;; is "x"
Neither print
, prin1
, princ
made a difference.
# nor does `coerce`
(coerce "\x27" 'list)
;; (#\x #\2 #\7)
So how then to distinguish in a string when "\x27" or any of such hexadecimal representation occurs?
- It turned out, one doesn't need to solve this to solve the task. However, now I still would like to know whether there is a way to distinguish "\x" from "x" in common lisp.
CodePudding user response:
The string literal "\x27"
is read as the same as "x27"
, because \
is an escape character in string literals. If you want a string with the contents \x27
, you need to write the literal as "\\x27"
(i. e. escape the escape character). This has nothing to do with the strings themselves. If you read a string from a file containing \x27
(e. g. with read-line
), then the four-character string \x27
results.
CodePudding user response:
By the time that the Lisp reader gets to work, \x
is the same as x
. There may be some way to turn this off - I wouldn't be surprised - but the original text talks about Santa's file.
So, I created my own file, like this:
x27
\x27
And I read the data into special variables like this:
(defun read-line-crlf (stream)
(string-right-trim '(#\Return) (read-line stream nil)))
(defun read-lines (filename)
(with-open-file (stream filename)
(setf x (read-line-crlf stream))
(setf x-esc (read-line-crlf stream))
))
The length of x
is then 3, and the length of x-esc
is 4. The returned string must be trimmed on Windows, or an external format declared, because otherwise SBCL will leave half of the CR-LF on the end of the read strings.