LISP: Помощь при чтении входного потока (с пробелами) в список символов - PullRequest
2 голосов
/ 21 марта 2011

Я пытаюсь написать программу, в которой мне нужно обрабатывать строку за символом, включая пробелы.Эта строка будет передана пользователем, запустившим программу, из стандартного потока ввода.

Я заметил, что функция (read) останавливается только после захвата некоторых непробельных символов и обрезает все, начиная сс первым пробельным символом.

Другими словами, если я выполню функцию (read) и введу hi to you, она вернет HI.То, что я хотел бы, чтобы моя функция вернула (#\h #\i #\Space #\t #\o #\Space #\y #\o #\u).Кто-нибудь может дать мне несколько советов о том, как этого добиться?Извините, ребята, я ОЧЕНЬ новичок в LISP, но мне он очень нравится.

РЕДАКТИРОВАТЬ: Одна вещь, которую я пробовал, это использовать (минусы) с (read-char).Например: (cons (read-char) (cons (read-char) (cons (read-char) (cons (read-char) (read-char))))).Когда пользователь вводит «привет», это выводит (#\h #\e #\l #\l . #\o), что близко, но что этот дополнительный период делает там?

Ответы [ 2 ]

5 голосов
/ 21 марта 2011

Xach в основном ответил на ваш главный вопрос: вы, вероятно, захотите прочитать строку с read-line и привести ее к списку: (coerce (read-line) 'list), а затем сделать что-то с этим списком.

Причина, по которойread не работает, потому что он читает и возвращает s-выражения:

> (car (read))
(foo bar baz) ; this is me typing

FOO

Так что он просто читает первый символ hi на входе "привет тебе" и останавливается.Последовательные вызовы read вернут остаток:

> (list (read) (read) (read))
hi to you ; me typing again

(HI TO YOU)

Возможно, вы все еще хотите использовать предложение Xach для получения вашего ввода.

Чтобы ответить на другой вопрос, причина в том, что точка вэтот список символов состоит в том, что выражение (cons (read-char) (cons (read-char) (cons (read-char) (cons (read-char) (read-char))))) оканчивается на (cons (read-char) (read-char)), которое состоит из двух символов вместе.

Cons создает "клетки cons" или пары Lisp, которые представлены в виде пунктирной пары:

> (cons 'a 'b)
(A . B)

Списки Lisp обычно формируются с nil или пустым списком в качестве последнего элемента.Но они на самом деле представлены в виде связанных списков с этими конс-ячейками, они одинаковы:

(a . (b . (c . ())))

(a b c)

Они обычно печатаются вторым способом.В вашем случае последний элемент является символом, поэтому он печатается в виде списка пунктирных хвостов.Поэкспериментируйте с ним в REPL, и это будет иметь смысл:

> '(a . (b . c))
(A B . C)

> '(a b . c)
(A B . C)

> '(a b c)
(A B C)

> '(a . (b . (c . nil)))
(A B C)

Итак, что вы хотели бы сделать с этим исходным выражением:

> (cons (read-char) (cons (read-char) (cons (read-char) (cons (read-char) (cons (read-char) nil)))))
(#\h #\e #\l #\l #\o)
3 голосов
/ 21 марта 2011

read-char вернет следующий доступный символ, а read-line вернет всю строку ввода в виде строки.Вы можете использовать coerce , чтобы изменить строку в список символов, например,

(coerce "foo" 'list) => (#\f #\o #\o)
...