2012-01-03 32 views
3

所以我一直在看D大約15分鐘,所以這也難怪我有問題,但一些奇怪的事情發生在我身上。特殊的writef/writefln行爲?

我從here安裝了D,從here安裝了Visual D,我在Visual Studio 2010 Professional中運行了所有東西。 D示例編譯並運行,調試器似乎工作正常。

同時通過dsource.org's fundamental tutorials去,我正在讀Wait節時,我注意到,如果你再暫停後的輸出打印的最後一行用writef代替writefln

這裏的例子代碼:

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"); 
} 

這裏是我的,注意,唯一的變化是writeflnwritef

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"); 
} 

隨着writef程序將顯示在屏幕上什麼都沒有,暫停在getch,那麼當我按下一個鍵時,我會看到提示:

Press a key (using 'std.c.stdio.getch();' to wait) . . .Waiting again 
Press any key to continue . . . 

但不是「(使用'system(」pause「);'):」。在按下某個鍵以通過控制檯中的「暫停」命令後,會出現括號聲明。如果我使用writefln,它會打印,等待,打印兩行文字,然後按照您的預期再次等待。

什麼解釋了這種行爲?

回答

6

在撥打writewritef後,使用stdout.flush();。後面的這些調用不會刷新緩衝區,這就是您看到這種行爲的原因。順便說一句getchstd.c.stdio(至少不是在D2?),它在DMC的CRT庫(SNN.lib),並正確地使用它,你將不得不原型作爲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"); 
} 

但是,這是由於getch()而不能跨平臺兼容。如果你想使用更好的用戶輸入設施,你可以看看Jesse的cmdln庫:https://github.com/he-the-great/JPDLibs/tree/cmdln。它有一個相當酷的界面:

auto num = require!(int, "a > 0 && a <= 10")("Enter a number from 1 to 10"); 
+0

對於'cmdln'庫的+1。很有意思。 – You 2012-01-03 00:20:52

+0

你可能會詳細說明'extern'行嗎?我刪除了不必要的導入,但代碼也沒有'extern'。 – 2012-01-03 03:55:45

+0

你正在使用哪種編譯器?用2.057沒有原型getch我得到'錯誤:未定義的標識符getch,你的意思是函數getc?' – 2012-01-04 00:29:03

4

This thread on gmane.comp.lang.d.learn似乎爲indicatewritef只在遇到換行符時刷新輸出。由於writefln是對writef的簡單調用,附加了一個換行符,因此writefln總是會刷新輸出。最後一個換行符後面的所有文本都會被緩衝,直到程序結束。