If you try this in the shell, I think that you'll find that it works as expected. (If it didn't, what would the problem be ? READ-CHAR or CHAR= not working in simple cases ?)
If you try it in an environment that tries to provide better support for editing lisp expressions (the CCL IDE, some Emacs environments like SLIME), those environments try to use an approximate knowledge of lisp syntax to send (what it thinks are) complete lisp expressions to the REPL (and to allow you to edit incomplete expressions.) If you type
(an open paren followed by a newline) to a Listener in the CCL IDE, you can backspace twice (erasing the newline and the #\() and type something else entirely. The REPL is still sitting there waiting for input; it won't "see" anything until the environment has concluded that you've typed one or more well-formed expressions followed by a newline.
The "environment"'s knowledge of lisp syntax is approximate, and I don't know of an environment that tracks changes to the readtable. When the environment sees that you've typed a newline after typing
? #"contains " and \."#
it sees a total of 3 #\" characters and is waiting for a closing #\" before any characters are available to READ and before your reader macro is even called.
Yes, this is confusing. As I said, you won't see this kind of thing if you run CCL in the shell (where the environment buffers lines before they're sent but has no knowledge of lisp syntax), but a richer environment will likely get confused by your extensions to lisp syntax.
Different development environments may behave differently. The textbook that you're reading can't possibly describe all of these differences, but I think that it's desirable for textbooks to make their readers aware of the general issue.
One common way to test reader macros (and similar things) without being affected by what I'm calling "the environmemt" is to use READ-FROM-STRING; if you do something like: