Question

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.

Was it helpful?

Solution

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)))))

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top