Basic noob question re console input

Discussion in 'C Programming' started by Robbie Brown, Feb 12, 2014.

  1. Robbie Brown

    James Kuyper Guest

    Your call to printf() doesn't include a newline character before calling
    fgets(). If stdout is unbuffered, it should work exactly as you expect,
    but that's pretty uncommon. stdout is normally line-buffered, in which
    case the user won't see any output until the next time your program
    prints a newline.
    stdout is permitted to be fully buffered only if the implementation
    cannot determine that stdout is connected to an interactive device.
    Systems where that can be determined are commonplace, and
    implementations for systems where it cannot be determined will generally
    not take advantage of that fact. However, if an implementation does
    choose to fully buffer stdout, the failure mode is even more confusing:
    if your call to printf() doesn't fill up the buffer, the user won't see
    anything. If it does fill up the buffer, the buffer will be output, but
    it's likely to be the case that only part of your prompt will be
    printed, the rest will be put at the beginning of the newly-flushed buffer.
    It is generally an extremely bad idea to fiddle with the contents of a
    FILE*. In addition to making your code unportable, there's a pretty good
    chance that your fiddling with that structure may interfere with use of
    It's the architecture of <stdio.h> that matters, the processor
    The fact that they work that way is highly system-specific. Don't expect
    any portability, whatsoever, of code that is based upon such assumptions.
    James Kuyper, Feb 14, 2014
    1. Advertisements

  2. Advancing the pointer by hand assumes you know the structure of the
    control data pointed to by stdin. Not all systems are intel based.
    Not all systems will use the naming convention yours does. Even the
    assumption that stdin points to a struct is unsupportable. And on
    what do you base your conclusion that setting stdin[0]._IO_read_ptr to
    the current value of stdin[0]._IO_read_end is either appropriate or
    Barry Schwarz, Feb 14, 2014
    1. Advertisements

  3. Robbie Brown

    Robbie Brown Guest

    cat /usr/include/libio.h
    Observation. Inspecting the values of the various pointers using gdb
    watching what happens call by call, line by line for several different
    functions that can be used to read stdin ... experimentation, testing
    and testing again ... but it's all a fair point, I've never had to worry
    about portability before, I thought it might be too good to be true.
    Robbie Brown, Feb 14, 2014
  4. It's not that uncommon. On Unix-like systems, at least in my
    experience, stdout is commonly unbuffered if it's writing to an
    interactive device.

    Streams can be unbuffered, line buffered, or fully buffered. Both ISO C
    and POSIX merely require stdout to be either unbuffered or line buffered
    if it refers to an interactive device, so you shouldn't depend on it
    being unbuffered.

    Adding `fflush(stdout);` after printing a partial line is good practice,
    and it makes your code more portable, but *on some systems* it may not
    make any visible difference in behavior.

    Keith Thompson, Feb 14, 2014
  5. In fact it's deeply evil. Unix programmers like to connect programs
    together with pipes. Which is great. Until you need some interactivity,
    or a two-way communication, a full duplex pipe in the jargon.

    Then you find that the pipes keep on hanging because of buffers. Process
    one says "Hello Fred" and process two replies, "Hi Bert". But process
    one never gets that "Hi Bert" message. It's lost in the pipes and
    buffers somewhere.
    Malcolm McLean, Feb 15, 2014
  6. Robbie Brown

    Jorgen Grahn Guest

    Then there are two of us!

    strtol() is better than atoi(), since it lets you detect parse errors.

    Jorgen Grahn, Feb 15, 2014
  7. Robbie Brown

    Jorgen Grahn Guest

    That's why they recommend against doing that. If you need to write to
    some program's stdin and read its answers from stdout, you should use
    something like expect(1). I think even the Perl and Python
    documentation says full duplex pipes don't work.

    The alternative would mean low thoughput for other pipelines and
    redirections, and some of those need to be as fast as possible.

    Jorgen Grahn, Feb 15, 2014
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.