Unbuffered I/O using MicroSoft C 3.0

Tom May tom at uw-warp.UUCP
Mon Jan 12 18:15:08 AEST 1987


In article <1867 at sunybcs.UUCP>, ugwayne at sunybcs (Wayne Nelligan) writes:
>     I am using MicroSoft C 3.0 and I have tried various methods but each time
> the printer only prints out when I enter a Carriage Return.  At first, I was
> using getc() and putc() and then it dawned on me that these functions
> use buffered I/O.  So I looked in the MicroSoft manuals and found the 
> function setbuf.  I tried this on the stream stdprn and then ran the program
> again.  It still didn't work.

What's going on is that your terminal input is line-buffered so you can use
backspace, function keys, etc.  A setbuf on stdin won't turn off this
buffering, since it is done by MS-DOS before the C library gets hold of
your characters.  You have to invoke MS-DOS directly, as demonstrated below.

>     Next, I used the functions read() and write() which the manual states as
> low-level I/O that do not buffer or format data.

That may be true, but the very-low-level I/O routines, i.e., MS-DOS, may still
buffer stuff.  And in fact they do, at least as far as terminal input is
concerned.

> Then, I thought that it might be that the printer was getting
> the characters one at a time (so the pogram was working) and it may need a
> Carriage Return before it does any printing (it had its own buffering).

Your printer could indeed do this type of buffering, especially if it is
bi-directional (wouldn't make a good typewriter in the first place anyway
if so).  If it does, you're out of luck.

>     With this in mind then I decided to just try my program with the standard
> input and output devices.  So when I hit a key, I would not only see my 
> keystroke but also another one which my program was then sending.  This too, 
> did not work, a Carriage Return was still needed. 

Interesting.  What should happen is you will see MS-DOS echo characters as you
type them, then when you hit return (after any line-editing) they will all
be handed to your program which would echo them again.  Weird.

So, here is the promised routine which invokes MS-DOS to get a
character from the keyboard (not stdin) without echoing it.  It also
does some things which are obvious from looking at the code.

#include <dos.h>
int
grokchar() {
    union REGS regs;

    regs.h.ah = 7;      /* get char no echo */
    intdos (&regs, &regs);
    return (regs.h.al == 26 ? EOF : regs.h.al == '\r' ? '\n' : regs.h.al);
}

The MS-DOS interrupts are documented in the MS-DOS Technical Reference
Manual, so if you want one that echos you can look it up there.  I think there
is also one to pass a character to the printer.

Stuff like this is why I think MS-DOS stands for Massively Suckful DOS.
Personally, I'd use either a real typewriter or an editor for this job.
-- 
Tom May.	uw-beaver!uw-nsr!uw-warp!tom
(So, do I pass the Turing test?)



More information about the Comp.lang.c mailing list