AmberWolfe
AmberWolfe

Reputation: 65

Scheme case error

I'm trying to create a word count program in Scheme. I think I've worked out an algorithm that'll count my lines, words, and chars, but when I start to run the program, it tells me "The object #\1 is not applicable." "1" is the first character in the file I'm reading, and it should fall under "else". Everything I look at matches my case statement, so I think I'm doing it right, but clearly something's messed up somewhere. Thank you for your help!

(define files
  (lambda (reading n)
    (begin
      (define in (open-input-file reading))
      (let loop ((lines 0)
         (words 0)
         (chars 0)
         (port (read-char in)))
       (case (port)
         ((#\newline)
           (loop (+ lines 1) words (+ chars 1) (read-char in)))
         ((#\space #\tab)
           (loop lines (+ words 1) (+ chars 1) (read-char in)))
         (else (loop lines words (+ chars 1) (read-char in)))))
  (close-input-port in)

  (display lines)
  (display " ")
  (display words)
  (display " ")
  (display chars)
  (newline)
  (display "Top ")
  (display n)
  (display " word(s):")
  (newline)
  '())))

Upvotes: 0

Views: 256

Answers (2)

schemer
schemer

Reputation: 1

How does the "let loop" know when you've reached the end of the file? What does read-char return when it hits the end? Hint: read about the eof-object? predicate. A predicate is a function that returns #t or #f. You may need to use a cond rather than a case to use this predicate

Also, the lines, chars and words variables are local to the named let, so you can't print then out "outside". (Hint: print them inside the loop when (eof-object? port) returns #t.

Style quibble: don't use the name "port" for the char that read-char returns. "in" is the port (file handle), Maybe you can use "ch" instead of "port".

Upvotes: 0

Sam Tobin-Hochstadt
Sam Tobin-Hochstadt

Reputation: 5053

Your problem is fortunately easy to fix. You've written:

(case (port) ...)

but that does a case on the result of calling the function port. Of course, port isn't a function, it's a character, so you just want:

(case port ...)

Upvotes: 2

Related Questions