[racket] Does read-char have an extra character in the stream on Windows?

From: 亀田馬志 (masashi.kameda at gmail.com)
Date: Fri Feb 14 17:50:07 EST 2014

Hello.

I wrote a tiny and silly joking program as below.

;;;;;;;;;;;;;;;;;;

#lang racket

(require srfi/48)

;;;;; Data

(define *script*
  #hasheq((intro . "Let me help to show you the age of marrage to be happy,
Lady!~%~%1. You need only one input later.~%2. If you'd like to step
forward, just hit the Enter/Return key.~%~%Do you want to play? [y/n]")
          (first-step . "~%At first, please call a two-digit number
whichever you like in your mind.~%Then please hit the Enter/Return key~%~%")
          (second-step . "Please add the one's digit and the ten's digit in
your mind.~%Then please hit the Enter/Return key.~%~%")
          (question . "Is the number still a two-digit number? [y/n] ")
          (third-step . "~%Next, please multiply the answer you've just got
by 9 in your mind.~%Then please hit the Enter/Return key.~%~%")
          (forth-step . "Now, Please add the one's digit and the ten's
digit of the answer you've just got in your mind.~%Then please hit the
Enter/Return key.~%~%")
          (fifth-step . "At last, please add the number of guys you've
slept with to the answer you've just got in your mind.~%Then please input
the answer you've got below.~%==> ")
          (conclusion . "~%You'd better get married when you are ~a years
old to have a happy life,~%and that implies you've slept with ~a ~a
~a.~%~%")
          (only . "only")
          (nothing . "")
          (man . "man")
          (men . "men")
          (play-again? . "Play again?")))

;;;;; Environment

(define *env* (hasheq 'phase #f 'messages *script*))

;;;;; Read

(define (y-or-n?)
  (let ((i (read)))
    (let ((sym (string->symbol (string-upcase (substring (symbol->string i)
0 1)))))
      (case sym
        ((Y) #t)
        ((N) #f)
        (else (raise 'not-yes-nor-no))))))

(define (parser x env)
  (case (hash-ref env 'phase)
    ((intro question play-again?) (values (y-or-n?) env))
    ((fifth-step) (let ((i (read)))
                    (values (if (integer? i)
                                i
                                (raise 'input-error)) env)))
    ((first-step
      second-step
      third-step
      forth-step) (read-char) (values x env))  ;;; THIS PART DOESN'T WORK
PROPERLY!
    (else (values x env))))

;;;;; Eval

(define (interp x env)
  (case (hash-ref env 'phase)
    ((intro play-again?) (if x
                             (values x (hash-set env 'phase 'first-step))
                             (exit)))
    ((first-step) (values x (hash-set env 'phase 'second-step)))
    ((second-step) (values x (hash-set env 'phase 'question)))
    ((question) (values x (hash-set env 'phase (if x
                                                   'second-step
                                                   'third-step))))
    ((third-step) (values x (hash-set env 'phase 'forth-step)))
    ((forth-step) (values x (hash-set env 'phase 'fifth-step)))
    ((fifth-step) (values (- x 9) (hash-set env 'phase 'conclusion)))
    ((conclusion) (values x (hash-set env 'phase 'play-again?)))
    (else (values x (hash-set env 'phase 'intro)))))

;;;;; Print

(define (print x env)
  (let ((c (hash-ref env 'phase))
        (s (hash-ref env 'messages)))
    (case c
      ((intro
        first-step
        second-step
        question
        third-step
        forth-step
        fifth-step
        play-again?) (format #t (hash-ref s c)))
      ((conclusion) (format #t
                            (hash-ref s c)
                            (+ x 9)
                            (hash-ref s (if (< x 2)
                                            'only
                                            'nothing))
                            x
                            (hash-ref s (if (< x 2)
                                            'man
                                            'men))))))
  (flush-output)
  (values x env))

;;;;; REPL

(define (main x env)
  (let-values (((x env) (parser x env)))
    (let-values (((x env) (interp x env)))
      (let-values (((x env) (print x env)))
        (main x env)))))

 (main #f *env*)

;;;;;;;;;;;;;;;;;;;;;; THE END OF PROGRAM

I would like to implement something like "HIT ENTER TO CONTINUE", and I
used read-char for it; however it doesn't work as I wished.
It seems like when I hit the enter key, it keeps having something other
than #\newline in the stream, and two messages of data are shown at once.
This is not what I mean.

I tried using charterm, but as implied, it does not work on Windows and
says ttf; therefore I gave up using the library on Windows.

Is there any good idea to implement "HIT ENTER TO CONTINUE"?

By the way, I'm using Windows 7 and Racket V.5.93.

Thanx.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20140215/04f4d933/attachment-0001.html>

Posted on the users mailing list.