What is the problem with this piece of code?

Discussion in 'C Programming' started by Alexander, Sep 17, 2010.

  1. Alexander

    Alexander Guest

    In my idea it should:
    - get the current time
    - print 'a'
    - do nothing until a second passes
    - print 'b':
    and repeat for eternity. Instead, it does nothing, and the program
    does not exit (probably enters into an infinite loop without producing
    any input).

    Thanks!

    #include <stdio.h>
    #include <time.h>

    int main() {
    char c = 'a';
    while(1) {
    time_t startTime = time(NULL);
    putchar(c);
    if (c < 'z') c++;
    else c = 'a';
    while(startTime == time(NULL));
    }
    }
     
    Alexander, Sep 17, 2010
    #1
    1. Advertising

  2. Alexander

    Mara Guida Guest

    On Sep 17, 4:50 pm, Alexander <> wrote:
    > In my idea it should:
    >   - get the current time
    >   - print 'a'


    You need to flush the output stream (or print a line break) to see the
    output.
    Try fflush(stdout) soewhere inside your loop.

    >   - do nothing until a second passes
    >   - print 'b':
     
    Mara Guida, Sep 17, 2010
    #2
    1. Advertising

  3. Alexander

    Alexander Guest

    Ok, thanks. I wasn't aware that when I call an output function, it's
    not immediately applied.
     
    Alexander, Sep 17, 2010
    #3
  4. Alexander <> writes:
    > In my idea it should:
    > - get the current time
    > - print 'a'
    > - do nothing until a second passes
    > - print 'b':
    > and repeat for eternity. Instead, it does nothing, and the program
    > does not exit (probably enters into an infinite loop without producing
    > any input).
    >
    > Thanks!
    >
    > #include <stdio.h>
    > #include <time.h>
    >
    > int main() {
    > char c = 'a';
    > while(1) {
    > time_t startTime = time(NULL);
    > putchar(c);
    > if (c < 'z') c++;
    > else c = 'a';
    > while(startTime == time(NULL));
    > }
    > }


    It's already been pointed out that output buffering is the problem.

    I'll also point out a couple of assumptions you're making.

    On many systems, time() returns an integer representing the number
    of seconds since a fixed point in the past, so its value changes once
    per second, but the standard doesn't guarantee that. If time() has a
    finer resolution (for example, if time_t is a floating-point type or
    represents a count of milliseconds), you might get a lot more output
    that you expect. Note that the resolution of the type time_t doesn't
    necessarily match the resolution of the values returned by time().
    You're not very likely to run into a system where this is an issue.

    The standard doesn't guarantee that the values of 'a' through 'z'
    are contiguous. If you were on an EBCDIC system, for example,
    you'd see some other characters, some of them undefined, between
    some of the letters. Again, unless you work with IBM mainframes,
    you're unlikely to run into this.

    The first iteration of the loop will take less than a second,
    depending on when you start the program.

    Your busy loop:

    while(startTime == time(NULL));

    could cause your program to consume a great deal of CPU time.
    This could be bad if you're on a multi-user, or even multi-process,
    system.

    Finally, just because I can't help myself, "int main()" is better
    written as "int main(void)".

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Sep 17, 2010
    #4
  5. Alexander

    Nobody Guest

    On Fri, 17 Sep 2010 12:54:53 -0400, Kenneth Brody wrote:

    >> Ok, thanks. I wasn't aware that when I call an output function, it's
    >> not immediately applied.

    >
    > Well, the putchar(c) is "immediately applied". However, FILEs can use
    > buffered I/O, and stdout, by default, uses "line buffering",


    Unix convention is that stdin and stdout are line-buffered when associated
    with a terminal, and fully-buffered (aka block-buffered) otherwise. stderr
    is always unbuffered.

    The ISO C standard is slightly less specific; 7.19.3.p7:

    As initially opened, the standard error
    stream is not fully buffered; the standard input and
    standard output streams are fully buffered if and only if
    the stream can be determined not to refer to an interactive
    device.

    POSIX mirrors the ISO C definition, but all real Unices (SysV, BSD,
    Linux) follow the stricter convention.
     
    Nobody, Sep 18, 2010
    #5
  6. Alexander

    Jorgen Grahn Guest

    On Fri, 2010-09-17, Keith Thompson wrote:
    ....
    > Your busy loop:
    >
    > while(startTime == time(NULL));
    >
    > could cause your program to consume a great deal of CPU time.
    > This could be bad if you're on a multi-user, or even multi-process,
    > system.


    Or even a single-process system where wasting cycles means wasting
    battery life, global warming and other nastiness ...

    (He probably knew already that busy loops are a bad idea, but perhaps he
    should have mentioned that he knew.)

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Sep 18, 2010
    #6
  7. On Fri, 17 Sep 2010 12:54:53 -0400, Kenneth Brody <>
    wrote:

    ....
    > Well, the putchar(c) is "immediately applied". However, FILEs can use
    > buffered I/O, and stdout, by default, uses "line buffering", meaning
    > that the output buffer isn't flushed until a newline is encountered, or
    > when the output buffer is full.
    >
    > By adding an explicit fflush(stdout) or putchar('\n') after the
    > putchar(c), you explicitly force the buffer to be flushed for every
    > character.


    It would be simpler to call setbuf(stdout, NULL) before starting any of
    the output, instead of having multiple calls to fflush().

    --
    Morris Keesan --
     
    Morris Keesan, Sep 20, 2010
    #7
  8. Kenneth Brody <> writes:
    [...]
    > I have to
    > explain the concepts of buffered I/O, and tell them to test it under an
    > environment closer to how it would be run from our program, with something like:
    >
    > cat -u | their_program | cat -u
    >
    > Then, they can immediately see that their program sends "no output" to the
    > screen until they add the necessary fflush(stdout).


    I think somebody already mentioned that the GNU coreutils version of
    "cat" ignores the "-u" option.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Sep 20, 2010
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Przemo
    Replies:
    5
    Views:
    543
    Teemu Keiski
    Jul 18, 2004
  2. Replies:
    6
    Views:
    436
    Keith Thompson
    May 17, 2006
  3. Jaco Naude
    Replies:
    9
    Views:
    788
  4. Patrick Plattes

    Download a file piece by piece

    Patrick Plattes, Nov 30, 2006, in forum: Ruby
    Replies:
    2
    Views:
    233
    Patrick Plattes
    Nov 30, 2006
  5. Guest

    problem with a piece of code

    Guest, Apr 6, 2004, in forum: Javascript
    Replies:
    2
    Views:
    152
    Dr John Stockton
    Apr 6, 2004
Loading...

Share This Page