2015-08-26 59 views
0

我已經通過使用copy_stream_data在SWI-Prolog中實現了一個cat程序。在SWI-Prolog中,當調用copy_stream_data時,如何避免「|:」提示?

文件args.pl

:- module(args, [withFilesOrUserInput/2]). 

withFilesOrUserInput(StreamFunction, []) :- 
    call(StreamFunction, user_input). 

withFilesOrUserInput(StreamFunction, [Filename]) :- 
    withFile(StreamFunction, Filename). 

withFilesOrUserInput(StreamFunction, [Head|Tail]) :- 
    withFile(StreamFunction, Head), 
    withFilesOrUserInput(StreamFunction, Tail). 

withFile(StreamFunction, Filename) :- 
    open(Filename, read, StreamIn), 
    call(StreamFunction, StreamIn), 
    close(StreamIn). 

文件cat.pl

:- use_module(args). 

main(Argv) :- 
    withFilesOrUserInput(catStream, Argv). 

catStream(Stream) :- 
    copy_stream_data(Stream, user_output), 
    flush_output(user_output). 

當我使用該程序來catstdinstdout,它打印的提示|:在那裏它應該從stdin輸入。我該如何避免這種提示?

+1

(不是一個答案,而是對你的代碼的評論)有'setup_call_cleanup/3'來正確處理這種情況。在你的版本中,失敗或錯誤的調用(StreamFunction,StreamIn)不會關閉流。如果你有幾個答案,你將嘗試訪問一個已經關閉的流。 – false

+0

雅我仍然在學習如何在Prolog中正確執行I/O。讓我們看看我什麼時候學習如何正確使用'setup_call_cleanup/3',也許今天,也許明天。然而,我沒有看到幾個答案會導致訪問一個已經關閉的流,但也許有一些我不明白的東西呢? –

回答

0

僅當stdout是終端時纔會出現|:提示。當stdout是一個文件時它不會出現。所以,當你的輸出被重定向到一個文件時,它不會在輸出中產生垃圾。但仍然不好。

爲了避免使用built-in predicate prompt及時,清晰,像這樣:prompt(_, ''),你可以插入到你的main(Argv)斷言:

main(Argv) :- 
    prompt(_, ''), 
    withFilesOrUserInput(catStream, Argv). 

你也可以把一個條款與prompt(_, '')謂詞在程序開始,通過插入的代碼的頂部以下內容:

:- prompt(_, ''). 

你甚至可以做到這一點的模塊中,在:- module()子句之後。

+0

以任何代價避免黑客攻擊。 – false

+0

@false你爲什麼認爲這是一種應該避免的黑客行爲?我不知道任何其他語言開始以這樣一種奇怪的方式提示,因爲當'stdout'是一個終端時,程序開始從'stdin'讀取。這甚至不合邏輯,我認爲這是一個錯誤。當「stdin」和「stdout」都是終端時,提示符纔有意義。但是當程序被稱爲'prolog -qt main cat.pl

+0

這是一個黑客攻擊,因爲你正在改變全局狀態,以寫出交互使用的東西。你雖然有一些點。其他更符合系統(例如SICStus)僅在輸入是終端時才顯示此提示。 – false

相關問題