Reputation: 24739
So I've been looking at D for about 15 mins, so it's no wonder I have questions, but something strange is happening for me.
I installed D from here and Visual D from here and I'm running everything in Visual Studio 2010 Professional. D examples compile and run and the debugger appears to be working fine.
While going through dsource.org's fundamental tutorials, I was reading the Wait section when I noticed that if you use writef
instead of writefln
then the last line of the output prints after the pause.
Here's the example's code:
import std.c.stdio; /* for getch() */
import std.process; /* for system() */
import std.stdio; /* for writefln */
void main() {
writefln("Press a key (using 'std.c.stdio.getch();' to wait) . . .");
getch();
writefln("Waiting again\n(using 'system(\"pause\");'):");
system("pause");
}
And here's mine, note the only change is writefln
to writef
import std.c.stdio; /* for getch() */
import std.process; /* for system() */
import std.stdio; /* for writefln */
void main() {
writef("Press a key (using 'std.c.stdio.getch();' to wait) . . .");
getch();
writef("Waiting again\n(using 'system(\"pause\");'):");
system("pause");
}
With writef
the program will display nothing on the screen, pause at getch
, then when I press a key I see the prompt:
Press a key (using 'std.c.stdio.getch();' to wait) . . .Waiting again
Press any key to continue . . .
but NOT "(using 'system("pause");'):". The parenthetic statement appears after I press a key to get through the 'pause' command in the console. If I use writefln
it prints, waits, prints both lines, then waits again as you'd expect.
What explains this behavior?
Upvotes: 3
Views: 261
Reputation: 3342
Use stdout.flush();
after any calls to write
or writef
. These latter calls don't flush the buffer, which is why you're seeing this behavior. Btw getch
is not in std.c.stdio
(at least not in D2?), it's in DMC's CRT library (SNN.lib), and to properly use it you would have to prototype it as extern (C) int getch();
:
extern (C) int getch();
import std.process; /* for system() */
import std.stdio; /* for writefln */
void main() {
writef("Press a key (using 'std.c.stdio.getch();' to wait) . . .");
stdout.flush();
getch();
writef("Waiting again\n(using 'system(\"pause\");'):");
stdout.flush();
system("pause");
}
But this is not cross-platform compatible due to getch()
. If you want to use a nicer user-input facility you can check out Jesse's cmdln library: https://github.com/he-the-great/JPDLibs/tree/cmdln. It has a rather cool interface:
auto num = require!(int, "a > 0 && a <= 10")("Enter a number from 1 to 10");
Upvotes: 6
Reputation: 23814
This thread on gmane.comp.lang.d.learn
seems to indicate that writef
only flushes the output when it encounters a newline. Since writefln
is a simple call to writef
with a newline appended, writefln
always flushes the output. All text after the last newline is buffered until the end of the program.
Upvotes: 4