簡體   English   中英

將命令行參數寫入文件

[英]Write command-line arguments to file

我在安排這項作業時遇到了麻煩。 我們應該將命令行參數作為輸入並將其寫到文件中。 到目前為止,我已經完成了以下代碼:

val args = CommandLine.arguments()

val a = length args;

val os = TextIO.openOut "rodr4719.txt";

TextIO.output(os, "rodr4719");


fun writeFile(os, args, a) = 


if a = -1 then

TextIO.output(os, "rodr4719")
TextIO.closeOut os
OS.Process.exit(OS.Process.success)

else

val str = nth (args, a);
TextIO.output(os, str ^"\n" );
a = a-1;
writeFile(os, args, a)
end;

writeFile(os, args, a-1)

我得到的錯誤是

.sml:22.1 Error: syntax error: inserting EQUALOP

這是以下兩個問答的重復:

以下是一些一般性反饋:

  • 縮進:您可以通過添加縮進使代碼更具可讀性。

     fun writeFile (os, args, a) = if a = -1 then TextIO.output(os, "rodr4719") TextIO.closeOut os OS.Process.exit(OS.Process.success) else val str = nth (args, a); TextIO.output(os, str ^"\\n" ); a = a-1; writeFile(os, args, a) end 

    (由於以下幾個原因,該代碼仍然被破壞。)

  • end當你只是宣布一個fun時,這個關鍵字是不必要的。 它在SML語法中的多個地方都有發生,特別是let ... in ... end ,您可能已經在那看到了。

  • 變量名:輸入參數的命名方式不同: os聽起來像是操作系統 ,可能是outstream的縮寫。 只是把它稱為outstream 有些人喜歡將它稱為文件描述符 fd ,但這全都與對目標讀者的理解有關。 args可能更通用:此函數可以編寫任何字符串列表,而不僅僅是命令行參數。 叫它lines a聽起來像它可以是任何類型,但它只是一個整數。 我將其稱為n ,但是實際上我不會使用數字來確定我的停止條件。

  • 分號:當函數執行具有副作用的多項操作時,可以使用; 操作員。 您未在隨后的部分中執行此操作,而在其他部分中執行了錯誤操作,這當然是因為; SML中的運算符在語法上 令人困惑

    簡短的版本: val foo = x; val bar = y;的分號val foo = x; val bar = y; val foo = x; val bar = y; val foo = (TextIO.output (fd, x); TextIO.output (fd, y))的分號不同。

    當您需要分號表達式運算符時,請將分號表達式包裝在括號或let表達式中。 否則,它將被解釋為(可選)分號聲明運算符。

  • 在迭代行列表時,不要保留計數器,而要在列表上執行模式匹配。 這大大簡化了遞歸結束的時間,因為無論如何總是總是一次尋址列表的頭。

  • 不要退出:完成后,您可能不想退出該程序。 退出功能就足夠了。 這樣,您可以在更復雜的控制流中重用該函數,而不必代表整個程序退出它。

  • 在同一范圍內打開和關閉文件:這是一般的編程建議:在處理副作用時,為確保您不會忘記關閉已打開的內容並且不會關閉兩次,在代碼的同一區域執行此操作可以使您更容易地推斷出正確性。 您可以創建一個始終處理打開和關閉的簡單函數

  • 函數體內的val當需要在函數體內或某些表達式內綁定臨時值時,請使用let -expression。 順便說一句,有人問為什么我要使用`let`而不是`val`來聲明SML函數內部的變量? 今天。

  • 不可變的值 :在SML中,您無法更新 a = a-1a = a-1值。 a不是變量,而是值綁定 您可以將其重新綁定到基於舊值的新值,從而遮蓋舊值,但這不是必需的。 而是使用更新后的值執行遞歸調用。

考慮到這些因素,我已經修改了您的程序:

fun writeFile (outstream, []) = ()
  | writeFile (outstream, line::lines) =
    ( TextIO.output (outstream, line ^ "\n") ; writeFile (outstream, lines) )

(* Demo *)
val myFile = TextIO.openOut "rodr4719.txt"
val _ = writeFile (myFile, CommandLine.arguments ())
val _ = TextIO.closeOut myFile

val _ = ... s是在頂層評估表達式而不在頂層直接擁有表達式的一種奇特方法。在交互式REPL foo(); ,單行表示val it = foo(); ,但是一旦編譯程序以生成獨立的二進制可執行文件,該方法就不再起作用val _ = ...基本上會在執行計算后丟棄計算結果,並且由於writeFileTextIO.closeOut return () ,他們不值得綁定任何東西。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM