Pergunta

I have to learn the basics of Scheme to complete a project, but I'm having a little difficulty constructing the equivalent of a while loop. For instance, in the following code, I want to have the user input a character. If the character is an x, I want to break out of the loop. If it is any other character, the character will be displayed, and the loop proceeds with the next iteration.

(define getUserChar (lambda ()
(define ch)
  (let loop ()
    (display "Enter character: ")
    (set! ch (read-char))
    (if (not (char=? ch #\x))
       (begin
       (display choice)
       (loop)
 )))))

This technically does work, but it skips an iteration. For example:

Enter character: a
Enter character:
Enter character: s

I am not able to input a character during that second iteration. I can't seem to pinpoint the problem. Any help is very appreciated.

Foi útil?

Solução

The problem is that you're actually reading two characters. The one you typed, plus the line break. I tried to preserve as much as possible from your original solution, and this is what I came up with:

(define getUserChar
  (lambda ()
    (define ch #\0)
    (let loop ()
      (display "Enter character: ")
      (set! ch (string-ref (read-line) 0))
      (if (not (char=? ch #\x))
          (begin
            (display ch)
            (newline)
            (loop))))))

IMHO a more idiomatic solution doesn't require a mutation operation, I prefer this one:

(define (getUserChar)
  (let loop ((ch #\0))
    (unless (char=? ch #\x)
      (display "Enter character: ")
      (let ((ch (string-ref (read-line) 0)))
        (display ch)
        (newline)
        (loop ch)))))

Outras dicas

This has to do with the fact that you are entering two characters in the very first iteration of the loop, namely "a\n" ("a~n") and that makes the second iteration just take the #\NewLine you entered together with the #\a as the character.

If you want to take a whole line at a time you get-line (R6RS) or read-line (R7RS) instead or look at buffer-mode (R6RS) and slurp the chars before starting the new iteration to continue using chars.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top