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. Advertisements

  2. Alexander

    Mara Guida Guest

    You need to flush the output stream (or print a line break) to see the
    output.
    Try fflush(stdout) soewhere inside your loop.
     
    Mara Guida, Sep 17, 2010
    #2
    1. Advertisements

  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. 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, Sep 17, 2010
    #4
  5. Alexander

    Nobody Guest

    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

    .
    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, Sep 18, 2010
    #6
  7. ....
    It would be simpler to call setbuf(stdout, NULL) before starting any of
    the output, instead of having multiple calls to fflush().
     
    Morris Keesan, Sep 20, 2010
    #7
  8. I think somebody already mentioned that the GNU coreutils version of
    "cat" ignores the "-u" option.
     
    Keith Thompson, Sep 20, 2010
    #8
    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.