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));
}
}
You need to flush the output stream (or print a line break) to see the
output.
Try fflush(stdout) soewhere inside your loop.
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) ks...@mib.org <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"
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.
Otherwise, after some amount of time, the buffer would be filled, and it
would be implicitly flushed. However, the buffer size on my implementation
is 512, meaning it would take 512 seconds before that were to happen here.
And, as I have seen buffer sizes of 4K, such a system would take over an hour.
--
Kenneth Brody
>> 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.
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 .
...
> 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 -- mke...@post.harvard.edu
In this simple case, where the only output is a single putchar(). However,
consider the implications where longer strings are output between fflush()es.
--
Kenneth Brody
Drifting into mildly OT territory, since this is partially
implementation-specific. However, I have run into the distinction between
"terminal" and "non-terminal" stdout streams and their buffering.
One feature of our program is the ability to open a two-way I/O stream to a
user program, send data to its stdin, and receive data from its stdout.
It's very common to get a report from a developer where it's "not working"
when run from within our program, but "works fine" when run from the command
line, with the user typing in the input, and seeing the output. 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).
--
Kenneth Brody
I think somebody already mentioned that the GNU coreutils version of
"cat" ignores the "-u" option.