使用printf保留特殊字符的格式

时间:2011-05-25 17:01:32

标签: f# printf

我从.net样式({0} ...)切换到printf样式的格式,并注意到特殊字符的格式不再被保留。 使用printf保留格式的技术是什么? 我正在做Printf.kprintf Log.Debug format之类的事情。

我理解StringFormat会生成文字字符串(prenends为@“”)但printf不会。

编辑: 我基本上想要保留格式,比如反斜杠。如果我打印出一个文件路径,我希望看到“C:\ Program Files ...”不受干扰,就像StringFormat会打印一样。

2 个答案:

答案 0 :(得分:3)

F#中有两种类型的字符串文字:普通字符串文字,看起来像"string"和逐字字符串文字,看起来像@"string"。无论哪种方式,字符串都会成为内存中.NET System.String类型的实例,它们本质上只是char值的序列。如果要创建包含某些字符(如反斜杠)的字符串,则在使用普通字符串文字时应该转义它们:"C:\\Program Files\\...",但在使用逐字字符串文字时不需要这样做:{{1 }}。无论哪种方式,内存中的值将由字符'C',':','\','P','r'等组成。您可能会发现忘记逃避反斜杠并不总是会导致问题,因为反斜杠只会在特定字符前面被解释为转义序列(所以你可以使用@"C:\Program Files\..."而不是"C:\Program Files")。

一旦值在内存中,"C:\test"String.Format系列函数的工作方式基本相同:

printf

你会发现所有这些值都是相同的(并且在正确的位置包含反斜杠)。同样地:

let sf1 = System.String.Format("{0}", "C:\\test")
let sf2 = System.String.Format("{0}", @"C:\test")
let pf1 = sprintf "%s" "C:\\test"
let pf2 = sprintf "%s" @"C:\test"

这些都是相同的,两者都被破坏了。

请注意let sf_bad = System.String.Format("{0}", "C:\test") let pf_bad = sprintf "%s" "C:\test" 不会撤消创建字符串文字时发生的错位 - 它无法知道用户实际上并不想在字符串中嵌入制表符。

答案 1 :(得分:2)

如果您使用printfn格式,%s系列函数会打印字符串而不会进行任何转义 (%s格式指定参数是字符串,应按原样打印):

> printfn "%s" "C:\\Test";;
C:\Test
val it : unit = ()

如果您使用%A(它指定参数是任何对象并且应使用F#语法打印 - 请注意,这适用于列表),行为会有所不同。虽然这甚至没有逃脱"字符:

> printfn "%A" "C:\\Test";;
"C:\Test"
val it : unit = ()