ZRWA001%DTUZDV1.BITNET@wiscvm.wisc.EDU (Helmut Waelder) (04/23/87)
Hi folks, I'm using TURBO Pascal 3.01A on a Tandon AT under MS-DOS 3.1 . The following program discovers a bug in turbos READ procedure: (*$R+,U+,B-*) (* I always use this directives *) program readbug; var r:real; a,b:char; begin readln(r,a,b); writeln(r:8:3,a,b); end. The input line contains a real number and two characters: 12.34 ET The output is: 12.340 E You will notice that the value of variable a is always a blank character and an input of: 12.34ET brings up an I/O error 10. So I think there must be always a blank after a read of a number. But is this standard pascal? A simple way out of this is to code readln(r,a,a,b); but it's not so easy to explain to the students in the programming course why they have to do this. Helmut Acknowledge-To: Helmut Waelder <ZRWA001@DTUZDV1>
ken@rochester.ARPA (Ken Yap) (04/23/87)
Well, let me guess what is going on. When read sees 12.34E it thinks an exponent is coming up. But the T invalidates that. It is possible to design the input reader so that it pushes the E back onto the input buffer when the T is seen. It's just that Turbo Pascal didn't implement this. So, yes it's a bug. Complain. I just tested Berkeley pi and the program works correctly there. Ken
jfjr@mitre-bedford.arpa (04/23/87)
I noticed similar behavior and wrote about it to info-ibmpc last summer. MS-DOS screws up buffering input into pascal programs (turbo-pascal) at least. I wrote a simple program program test(input,output); var ch:char; begin writeln('enter character'); read(ch); writeln(ch); end. (its been a while since I wrote pascal so to anybody who will remark on any syntax/semantic errors rest assured those battles were fought last summer) If you compile and run this with Turbo (com option) and respond with a string say "abc", then the program will run correctly the first time, echoing an a. The second time you run it it will ignore you're input, whatever that may be and echo a 'b'. This will go on until the string 'abc' including cr and lf are consumed. I should back off a little. I havent tried it since last summer and turbo and/or MS-DOS might have been fixed since then but it drove me nuts then. The moral of this story (I have had similar input buffering problems with stdin in Micro-soft C) is that one should be very careful with standard input, console etc on an MS-DOS machine. By the way it didn't seem to matter what compiler options I chose Jerry Freedman,Jr
Slomcenski.WBST@Xerox.COM (04/24/87)
> > I noticed similar behavior and wrote about it to info-ibmpc >last summer. MS-DOS screws up buffering input into pascal >programs (turbo-pascal) at least. I wrote a simple program > >program test(input,output); > >var ch:char; > >begin >writeln('enter character'); >read(ch); >writeln(ch); >end. > >If you compile and run this with Turbo (com option) >and respond with a string say "abc", then the >program will run correctly the first time, echoing an a. The second time >you run it it will ignore you're input, whatever that may be and >echo a 'b'. This will go on until the string 'abc' including cr and lf >are consumed. I should back off a little. I havent tried it >since last summer and turbo and/or MS-DOS might have been fixed >since then but it drove me nuts then. The moral of this story In fact TURBO and/or MS-DOS aren't broke in this case! I believe that what you are seeing is the fact that MS-DOS "remembers" up to 16 characters typed at the keyboard in its internal type-ahead buffer. To guarantee that one and only one char is read by the program, the internal type-ahead buffer should be flushed by either an MS-DOS call (facilities to flush any remaining keys is provided by MS-DOS), or by TURBO code like: while keypressed do read(ch); The following should do what you expect it to: program test(input,output); var ch:char; begin while keypressed do read(ch); (* flush any old chars in kbd buffer *) writeln('enter character'); read(ch); writeln(ch); end. ~Bob
Slomcenski.WBST@Xerox.COM (04/24/87)
> >readln(r,a,b); >writeln(r:8:3,a,b); > > >The input line contains a real number and two characters: >12.34 ET >The output is: > 12.340 E > >an input of: >12.34ET >brings up an I/O error 10. The catch is that the format of a real may (or may not) contain the scientific notation 'E+xx' or 'E-xx' following the digits. In the first case, readln interprets '12.34' as the real (the number terminates when TURBO finds any char that is not part of the real format, in this case ' '). In the second case, readln sees the scientific notation '12.34E' and expects the next char to be a '+', '-', or the digits indicating an exponent. When it encounters the 'T' -- it generates the I/O error 10. >So I think there must be always a blank after a read of a number. > Input of a number DOES NOT have to be followed by a ' '!! In fact, in the first case, the blank is interpreted as the value for the char variable a. The second case would have worked fine except that the char after the digits happened to be 'E' which is STILL part of a real number representation. ~Bob
ZRWA001%DTUZDV1.BITNET@WISCVM.WISC.EDU (04/24/87)
Hi folks, I have seen: my example was mad. The problem is not the E after a integer or real number, the problem is: every character immediatly after the last digit of the number causes an I/O error except for the blank. And when I read a character after a number, the only character I can get correctly is a blank. This is not a problem of the input buffer, this is a problem of the read procedure of turbo. It's absolutely impossible to read a character other than blank after a number. And this is *NOT* Standard Pascal. Sorry for the stupid example with the 'E' after the real number :-) Helmut Acknowledge-To: Helmut Waelder <ZRWA001@DTUZDV1>
kvancamp@ARDEC.arpa (04/24/87)
>I don't care what >anybody says about buffering, programs shouldn't behave >that way. This kludgy MS-DOS buffering makes life real interesting >when you are inheriting stdin and stdin has been redirected from >a file. I have to agree with this remark. But then, Pascal never had any decent I/O to begin with -- just look at its unforgiving reads of reals. That's why I (and most people I know who need to read numeric data in Pascal) use my own general-purpose input routine that reads a line of data as a string (using readln, not read), then evaluates it byte-by-byte to decode the answer in a reasonable way. The one I use most is meant to read any number of reals, but is easily adapted to include chars. It's a simple routine, but if anyone would like a copy let me know. --Ken Van Camp <kvancamp@ARDEC.ARPA>
bobmon@iuvax.UUCP (Che' Flamingo) (04/26/87)
Slomcenski.WBST@Xerox.COM writes: >> >>readln(r,a,b); >>writeln(r:8:3,a,b); > >>The input line contains a real number and two characters: >>12.34 ET >>The output is: >> 12.340 E >> >>an input of: >>12.34ET >>brings up an I/O error 10. > [...] > >>So I think there must be always a blank after a read of a number. >> > >Input of a number DOES NOT have to be followed by a ' '!! In fact, in the >first case, the blank is interpreted as the value for the char variable a. >The second case would have worked fine except that the char after the >digits happened to be 'E' which is STILL part of a real number representation. According to my v3.0 manual (p.109), With a numeric variable (Integer or Real), Read expects a string of characters which complies with the format of a numeric constant of the relevant type as defined on page 43. [ e.g., exponents -- RAM] Any blanks, TABs, CRs, or LFs preceding the string are skipped. The string must be no longer than 30 characters, **and it must be followed by a blank, a TAB, a CR, or a Ctrl-Z. If the string does not conform to the expected format, an I/O error occurs.** [emphasis is mine -- RAM] As far as I can see, you must either use a dummy variable to absorb the blank, or (if you know how long the number is and it's REALLY important) read the number as a character string and parse it yourself. Or terminate the number with a carriage-return. ~-~-~-~-~ RAMontante bobmon@iuvax.cs.indiana.edu -OR- {?}!iuvax!bobmon Computer Science Indiana University "Have you hugged ME today?"