Reputation: 65
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
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
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