2010-03-10 112 views
13

有沒有人知道是否有一個內置函數從控制檯讀取printfn函數? 迄今爲止我所見過的唯一方法是使用System.Console.Read(),但它不像使用像printfn這樣的結構的功能。從控制檯讀取F#

回答

16

這確實是一個恥辱,沒有這樣的內置函數。但是,正如Brian在對Benjol的回答評論中所提到的那樣,可以自己構建一個scanf函數。這裏有一個如何定義一個sscanf變種速寫,雖然只有%s佔位符實現:

open System 
open System.Text 
open System.Text.RegularExpressions 
open Microsoft.FSharp.Reflection 

let sscanf (pf:PrintfFormat<_,_,_,_,'t>) s : 't = 
    let formatStr = pf.Value 
    let constants = formatStr.Split([|"%s"|], StringSplitOptions.None) 
    let regex = Regex("^" + String.Join("(.*?)", constants |> Array.map Regex.Escape) + "$") 
    let matches = 
    regex.Match(s).Groups 
    |> Seq.cast<Group> 
    |> Seq.skip 1 
    |> Seq.map (fun g -> g.Value |> box) 
    FSharpValue.MakeTuple(matches |> Seq.toArray, typeof<'t>) :?> 't 


let (a,b) = sscanf "(%s, %s)" "(A, B)" 
let (x,y,z) = sscanf "%s-%s-%s" "test-this-string" 
+7

當我需要更完整版本的'sscanf',擴展這段代碼非常容易。在這裏查看結果:http://fssnip.net/4I – wmeyer 2011-05-12 17:53:49

+0

@wmeyer - 太棒了! – kvb 2011-05-12 20:00:11

+0

@wmeyer:你有興趣爲FSharpx做出貢獻嗎? https://github.com/fsharp/fsharpx – 2011-10-31 23:24:47

1

據我所知,沒有。

這將是得心應手代碼高爾夫球:)

+3

這是一個恥辱的'printfn'函數本身依賴於編譯器魔法 - 你不能讓你自己的F#'的sscanf 「非常好。 – 2010-03-10 11:34:54

+4

你可以這樣做,我想。唯一的妙處是字符串文字可以被強制轉換爲PrintfFormats,此時這些類型會被顯示出來:let pf():PrintfFormat <_,_,_,_> =「%d%s」 – Brian 2010-03-10 16:11:48