Ascii writes all the classic ascii characters to standard output or, if redirected, to a file. If run without redirection the programs seems to perform as expected. We get all the ascii characters including a line feed, chr(10), and a carriage return, chr(13). However, when we redirect the output to ascii.all and then display ascii.all using
type we get considerably less output.
DOS displays various "non printing" characters as various symbols. Chr(1) is a smiley face. Chr(2) is a reverse smiley face. The next four characters, chr(3) .. chr(6) are the four suites of a deck of cards, etc.
The output of ascii.all via
type is two lines. The first is short, ending with a diamond. Then other characters do not print but actually do something. Chr(7) gives us a beep. Chr(8) backspaces.
Of particular interest is chr(10), a line feed, which causes the cursor to drop down a line, and chr(13), a carriage return, which sends the cursor to the left edge of the screen causing subsequent characters to overwrite whatever was there.
When we get to chr(25) we get an arrow pointing down and the output terminates. Why? Because DOS uses the next char, chr(26), as end-of-file. Thus when we redirect output to ascii.all that’s as far as we get. When we use
type to look at the file, that’s all there is.
On page 16 K&P present the following exercise.
"What happens if the last character of input to linecount is not a NEWLINE? Does the program stay sane? Is its behavior a bug or a natural consequence of our definition of a 'line'?"
ascii.all is just such a file, one whose last character is not a NEWLINE (CR + LF).
Linecnt < ascii.all
The answer is two. Why? Because the first ReadLn reads until it finds the carriage return. The second reads until it finds the end of file. In my opinion the output is sane and correct, and the behavior is not a bug.
I think K&P’s version would behave the same way if implemented in Turbo Pascal. Other implementations of Pascal might give different results.