TIP: Click on subject to list as thread! ANSI
echo: os2prog
to: John Poltorak
from: Ed Blackman
date: 1995-03-30 01:22:52
subject: scanf

On  in a message to All, John Poltorak wrote:

JP>         printf("Enter length: ");
JP>         scanf("%d", &len);
JP>         printf("Enter width: ");
JP>         scanf("%d", &width);
JP>         printf("area is %d", len * width);

JP> When I run this program, I don't get any prompts, before
JP> entering any values. Is this just a quirk of using an OS/2
JP> compiler, or is Mr. Schildt in error here?

JP> I'm using ICC from C Set/2 v1.0 and this is what the output looks like:-
[...]
JP> Having just installed emx+gcc, I now get the expected results, viz:
[...]

The buffering of i/o streams is implementation defined - neither CSet
nor EMX is wrong, merely different.

What the heck is "buffering of i/o streams", you ask?  Well, when you
open an i/o stream, you get a buffer, kind of a mini-disk cache,
associated with that stream.  printf() writes to stdout, which is one of
the standard i/o streams that get opened by your compiler's startup
code.  So when you call printf(), you're really writing into a buffer,
not the screen.  The stuff you told printf() to write doesn't show up on
the screen until that buffer is flushed.

Now, there are three main ways of managing this buffer, described below.
A compiler vendor chooses one of these three ways, and sets it as the
default management scheme.  If a programmer wants an individual stream
buffered a different way, he uses the setvbuf() function to change the
stream management for that stream.  If he wants to buffer all streams a
different way, he either gets a different compiler that buffers streams
the way he wants them buffered, or he consults a better C expert than
me, since I have no clue how to do that.  :-)

The first way to buffer a stream is to take each character out of the
buffer and send it to its destination immediately after it is placed in
the buffer.  This is called (surprise) "unbuffered".

The second way is called "fully buffered".  The buffer is only flushed:
    - when it is completely full,
    - when the programmer explicitly flushes it (with fflush()), and
    - just before the program ends, if there's still stuff in it.
This is what CSet was doing:  you put stuff in the buffer, but not
enough to fill it, and you didn't explicitly flush it, so it just sat in
there until just before your program ended.

The third way is called "line buffering".  The buffer is flushed in all
the cases that it would be flushed in if it was fully buffered, plus:
    - when a newline (\n) is put into the buffer, and
    - when input is asked for.
This is what EMX was probably doing.  When you asked for input with the
scanf() lines, the buffer was flushed.  It's also possible that EMX was
using unbuffered streams, but I think it's rather unlikely, because
unbuffered streams are pretty inefficient, especially under protected
mode operating systems like OS/2.  (Is that going to be enough of a
topical link to avoid the wrath of the moderator? :-)

I hope this explains what was going on.  If not, join me in the C_Echo,
since this doesn't have much to do specifically with OS/2 programming.


Ed Blackman

... Avoid "off topic" warnings:  Add the moderator to your twitlist!
--- Blue Wave/Max v2.12 OS/2 [NR]
* Origin: The Federal Post -{*}- Spring-Lake, NC (1:3634/2)
SEEN-BY: 105/42 620/243 711/401 409 410 413 430 807 808 809 934 955 712/407
SEEN-BY: 712/515 628 704 713/888 800/1 7877/2809
@PATH: 3634/2 151/1000 1002 3615/50 396/1 270/101 105/103 42 712/515 711/808
@PATH: 711/809 934

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.