Um. Кажется, за этим вопросом стоит пара ошибочных предположений. Короткий ответ «Нет» (хотя я уверен, что какой-то достаточно умный интриган может доказать, что я не прав), но позвольте мне взглянуть на те предположения, которые я упомянул.
Чтение непосредственно в локальные переменные
Как правило, вы не хотите этого делать. В такой ситуации, как ваша, когда вам нужен сложный ввод, вы хотите разделить эти проблемы на две функции. Один для получения и организации ввода, а другой - для создания объекта, полученного на табло. Что-то вроде:
(define scoreboard (x y z)
(cond ((eof-object? x) empty) ...))
; not sure what returning the function
; at the end was supposed to do
(define scoreboard-input ()
(let ((x (read)))
(cond ((string=? x "score") (list x (read) (read)))
((string=? x "highscore") x)
...)))
В зависимости от пользовательского ввода для форматирования
Предоставление пользователю информации о том, какой формат использует ваша доска, не кажется хорошей идеей. Это признак того факта, что вы пытаетесь заставить одну функцию выполнять слишком много (если я правильно понимаю, она пытается принять новые записи на табло и вывести отсортированную доску). Небольшое количество государства может быть вашим другом здесь; для того, чтобы составить правильное табло, я бы назначил место для отслеживания данных и предоставлял пользователю некоторые функции для простого и последовательного манипулирования ими (хорошо, я обыкновенный Лиспер по дням, поэтому я бы использовал методы , но все же).
(define *board* '())
(define (new-entry scoreboard player score)
(set! scoreboard (cons (player . score) scoreboard))
(define (show-scores scoreboard)
(let ((highest (car scoreboard))
(rest (cdr scoreboard)))
(printf "High Score: ~a at ~a" (car highest) (cdr highest))
(map (lambda (entry)
(printf "Player: ~a ~n Score: ~a" (car entry) (cdr entry)))
(sort scoreboard #:key cdr >))))
Таким образом, нет необходимости читать неструктурированные данные. Вы используете функцию new-entry
для добавления новых результатов и show-scores
для вывода текущего состояния доски. Возможно, вы захотите разложить его немного дальше, чем я, на самом деле, выделив функцию для получения отсортированной доски и, возможно, для получения верхнего имени.
В ответ на ваше редактирование:
Да, мои комментарии применимы, даже с измененными параметрами.
- отделение ввода от внутренней логики все еще хорошая идея
- полагаться на то, что пользователь читает как можно меньше, все еще хорошая идея
- надлежащим образом абстрагировать проблему в функции, составляющие ваше решение, все еще хорошая идея
Вы определенно хотите каким-то образом сохранить scoreboard
(лучший метод хранения оставлен в качестве упражнения для читателя; я использую alist
выше, но вы можете использовать хеш, или дерево, или объект / список объектов или пара последовательностей точно так же), и вы захотите реализовать для него три функции
(defun (record-score! scoreboard name score) ...)
=> nil
, добавляет счет на табло
(defun (best-score-by scoreboard name) ...)
=> (list name score)
или "?"
(defun (high-score scoreboard) ...)
=> score
Затем напишите функцию чтения, которая принимает пользовательский ввод и возвращает форматированный вывод одной из этих операций, в зависимости от ситуации. Вы определенно не не хотите писать одного гиганта cond
, если только по какой-то причине вам не нравятся головные боли.