2014-10-31 58 views
3

因此,我有一個程序(遊戲),旨在通過鍵盤從人類獲取輸入。但是,我希望在某些時候,我可以從用戶身上取得控制權併爲他們做出某些決定。雖然可以編寫特殊情況代碼以便在事件強制仿效用戶輸入的影響時使用,但我更願意覆蓋輸入流(在這種情況下爲cin),以便程序實際上沒有任何反應強迫他們做出決定,而不是用戶根據自己的意願作出這樣的決定。如何使用C++寫入cin輸入流

我已經嘗試寫入它,就像我會輸出流(例如cin<<'z'),但< <運算符未定義爲cin,我不知道如何定義它。

寫入鍵盤緩衝區會更好嗎?如果是這樣,我將如何以系統不可知的方式做到這一點?

回答

8

寫入輸入是相當黑客行爲。這將是更清潔的設計,以在實際輸入(如cin)和對該輸入進行操作的遊戲之間放置一個抽象層。然後,您可以重新配置此抽象層以響應程序生成的命令,而不必根據需要對cin進行響應。

+0

因此,將所有來自cin的輸入拉入具有自定義功能的緩衝區,然後將其作爲程序的輸入流進行操作?恐怕你沒有以我熟悉的方式使用「抽象層」。這聽起來像它會起作用,但是,謝謝! – Lurker 2014-10-31 09:29:26

+0

@Lurker是的,類似的東西。或者有一個'InputSource'接口,一個用於'cin'的實現,一個用於「程序生成」,並在必要時切換這些接口 - 對'cin'的抽象。 – Angew 2014-10-31 09:41:22

+0

@Lurker它被稱爲裝飾器,至少如果抽象模擬一個'std :: istream'。 (實際上,它是'std :: cin'使用的streambuf,你想要修飾它。) – 2014-10-31 09:57:44

0

我相信寫入cin是一個設計不好的程序的症狀。

你可能實際上想要有一些event loop這當然是操作系統特定的。在Posix和Linux上,你可以在系統調用poll(2)之上構建它,並且你可能想從你自己的進程到它自己設置一個pipe(7)

幾個庫提供了一些事件循環:libeventlibev,也框架,如QtGtkPOCOlibsdl ...(其中有些是移植到多種操作系統,所以給你的OS之上的抽象。 ..)

+0

實際上,cin.putback(char)是標準的必需部分,並且已更新爲在C++ 11中更好地工作它仍然受支持。我認爲增加一個抽象級別是解決我個人問題的最佳解決方案,但我沒有看到爲什麼重寫輸入流通常是一個壞主意,而cin也不例外。 – Lurker 2014-10-31 20:47:35

2

您可以將流緩衝到std::cin,是這樣的:

class InjectedData : public std::streambuf 
{ 
    std::istream* myOwner; 
    std::streambuf* mySavedStreambuf; 
    std::string myData; 
public: 
    InjectedData(std::istream& stream, std::string const& data) 
     : myOwner(&stream) 
     , mySavedStreambuf(stream.rdbuf()) 
     , myData(data) 
    { 
     setg(myData.data(), myData.data(), myData.data() + myData.size()); 
    } 
    ~InjectedData() 
    { 
     myOwner->rdbuf(mySavedStreambuf); 
    } 
    int underflow() override 
    { 
     myOwner->rdbuf(mySavedStreambuf); 
     return mySavedStreambuf->sgetc(); 
    } 
}; 

(我沒有測試過這一點,所以可能會有誤差,但基本原則 笑。 ULD的工作。)

std::cin構建的這個實例作爲論據 將從data返回字符,直到實例是 破壞,或所有字符都被消耗。

+0

+1,有時也顯示X-Y問題的Y部分的答案也很有用。 – Angew 2014-10-31 10:03:21

+0

非常好。特別是,這看起來像任意時間長度的字符串都能很好地工作,因爲您可以隨時離開人工輸入。 – Lurker 2014-10-31 20:51:04

+0

@Lurker您甚至可以暫時將輸入切換到文件,如果這是您需要的;例如,我使用類似的方法來處理宏觀擴展幷包含設施。我也用它來重新格式化輸入:剝離註釋,處理延續線等。 – 2014-11-03 09:36:57