Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!cs.utexas.edu!uunet!yale!haveraaen-magne From: haveraaen-magne@CS.YALE.EDU (Magne Haveraaen) Newsgroups: comp.lang.pascal Subject: Re: Standard Pascal Message-ID: <66375@yale-celray.yale.UUCP> Date: 13 Jul 89 21:19:49 GMT References: <20239@adm.BRL.MIL> Sender: root@yale.UUCP Reply-To: haveraaen-magne@CS.YALE.EDU (Magne Haveraaen) Organization: Yale University Computer Science Dept, New Haven CT 06520-2158 Lines: 79 In article <20239@adm.BRL.MIL> RDK%vm.temple.edu@cunyvm.cuny.edu (Robert Keiser) writes: >[...] Then to read anything, you >first would have to issue a blank readln followed by your read. The code >would look something like this: > . > . > . > WRITELN('WHAT IS YOUR NAME'); > READLN; (* FORCE A GET *) > I := 1; > WHILE NOT EOLN DO > BEGIN > READ(NAME[I]); > I := I + 1; > END; > . > . > . >Sorry about all caps but the Cyber doesn't have upper/lower case (normally) >[...] >As far as the I/O being one of Pascal's strengths, try explaining the above >example to a beginner. I've tried, the response is usually a quizzical look >and a shaking head. Explaining this programming style isn't so difficult, unless your student has a background from ForTran, or, which is sadly a very common case, the Pascal textbook author has a background in Fortran, and thus gives all kinds of misleading guidelines on how to program dialogues in Pascal. In Pascal 'readln' does not read-a-line, but reads-to-the-next-line. It acts as a synchronization utility, synchronizing the writeln with the next input line, removing all unwanted trailing characters from the preceding input line. That is why you should not supply the 'readln' procedure with any parameters, as these parameters will be given values from the previous inputline, before the synchronization takes place. But some dialects of Pascal did not conform to this, and it seems that most textbook writers have tested their programs on compilers that have non-standard input handling, making the teaching of standard Pascal quite difficult. Over to the more general question of get/put vs. read/write. The example skip-blanks is a good one: procedure skipBlanks (var input : text); (* note input is a file variable parameter, not the textfile input *) (* routine advances file pointer over blanks to the point where something interesting may be read *) begin while (input^ in [space, tab, newline, cr, formfeed]) do get (input) end; So let us use this in a program: program niceDialogues (input, output) ; : var age : integer; : begin : writeln('How old are you (type ''N'' if you don''t want to tell)? '); skipBlanks(input); if input^ in ['0'..'9','N','n'] then case input^ of '0'..'9' : begin read(age); ... end; 'N','n' : writeln('OK - just keep it a secret!') end else writeln('I assume you don''t want to tell me anyway.'); : end. Note how I can rely on the built-in 'read' procedure to convert the text-string to integers when reading 'age', without having problems with the non-numeric reply alternative. To do the equivalent without get/put would require 'skipBlanks' to return the character it stopped reading (as noted by Scott Schwartz ), and would force me to write my own 'readIntegerFromACharacterVariableAndTextFile' procedure. Magne