user618815
user618815

Reputation:

Racket eof-object read from input port

I tried to read string from an input-port in Racket, but no matter what API functions I used to read (read, read-string, read-bytes etc), the return value of those functions was never equal eof-object.

(define (some_process inp)
 (begin
    (let ([c (read-string 1 inp)])
      (if (eof-object? c)
          (begin
            (display "EOF \n")
            #f)
          (if (equal? c "\n")
              (begin 
                (display "NEWLINE \n"))
              (some_process inp))))))

The c can never be an eof-object?

If you display what c is, it is always a newline.

Upvotes: 3

Views: 6146

Answers (2)

C. K. Young
C. K. Young

Reputation: 223183

If you are entering your input from the console, try pressing Ctrl+D (in Unix and MacOSX), or Ctrl+Z, then Enter (in Windows). This will signal the end of the input.

Upvotes: 1

Yasir Arsanukayev
Yasir Arsanukayev

Reputation: 9686

Read reference:

  • read-char: "Reads a single character from in – which may involve reading several bytes to UTF-8-decode them into a character. If no bytes are available before an end-of-file, then eof is returned."

  • read-string: "Returns a string containing the next amt characters from in. If no characters are available before an end-of-file, then eof is returned."

Examples:

> (read-char (open-input-string "char"))
#\c
> (read-string 50 (open-input-string "the string"))
"the string"
> 

But if there are no character(s) in the buffer, you'll get eof:

> (read-char (open-input-string ""))
#<eof>
> (read-string 50 (open-input-string ""))
#<eof>

I think you just want to read some amount of characters in a loop and do something with them. If so, the solution would look something along the lines of:

(define (another-process inp)
  (let ([c (read-char inp)])
    (if (eof-object? c)
        (begin (display "==== EOF ====") (newline))
        (begin (display c) (newline)
               (another-process inp)))))

Example:

> (another-process (open-input-string "OK"))
O
K
==== EOF ====
> (another-process (open-input-string ""))
==== EOF ====
>

Notice a second call to another-process with an empty line, it detects eof immediately and exits the loop.

EDIT: In case you need to check if the read character is newline:

(define (process-moo inp)
  (let ([c (read-char inp)])
    (cond
      ((eof-object? c)
       (display "==== EOF ====") (newline))
      ((eq? c #\newline)
       (newline) (display "---- NEWLINE ----") (newline)
       (process-moo inp))
      (else
       (display c)
       (process-moo inp)))))

Example:

> (call-with-input-string "Hello\nhumans\n!" process-moo)
Hello
---- NEWLINE ----
humans
---- NEWLINE ----
!==== EOF ====
> 

Hope that helps.

Upvotes: 4

Related Questions