Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!rutgers!ames!ucbcad!ucbvax!decvax!tektronix!uw-beaver!tikal!sigma!uw-nsr!uw-warp!tom From: tom@uw-warp.UUCP (Tom May) Newsgroups: comp.lang.c,comp.sys.ibm.pc Subject: Re: Unbuffered I/O using MicroSoft C 3.0 Message-ID: <645@uw-warp.UUCP> Date: Mon, 12-Jan-87 03:15:08 EST Article-I.D.: uw-warp.645 Posted: Mon Jan 12 03:15:08 1987 Date-Received: Mon, 12-Jan-87 21:51:28 EST References: <1867@sunybcs.UUCP> Organization: The Warp, Seattle, WA Lines: 59 Summary: How to do it Xref: mnetor comp.lang.c:659 comp.sys.ibm.pc:918 In article <1867@sunybcs.UUCP>, ugwayne@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. #includeint grokchar() { union REGS regs; regs.h.ah = 7; /* get char no echo */ intdos (®s, ®s); 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?)