2016-03-28 8 views
4

Wie verwendet man sprintf zum Formatieren einer Ganzzahl, um Kommas als Tausendertrennzeichen anzuzeigen?Verwenden von sprintf zum Formatieren einer Ganzzahl mit Kommas als Tausendertrennzeichen

Ich weiß, wie es mit String.Format funktioniert, aber ich kann keinen Weg finden, es mit Sprintf zu tun.

EDIT: Basierend auf Fjodor Soikin Kommentar unten, habe ich versucht, diesen Code:

printf "%a" (fun writer (value:int) -> writer.Write("{0:#,#}", value)) 10042 
let s = sprintf "%a" (fun writer (value:int) -> writer.Write("{0:#,#}", value)) 10042 

Die printf funktioniert (aber schreibt auf die Standardausgabe, während ich einen String erhalten möchte ich den Text zuordnen können oder Inhaltseigenschaft eines WPF-Steuerelements zum Beispiel).

Der Sprintf-Aufruf schlägt mit Fehler fehl. FS0039: Das Feld, Konstruktor oder Element 'Schreiben' ist nicht definiert.

Wenn ich diesen Fehler beheben könnte, dann könnte dies die direkteste Lösung sein, die möglich ist, und in Kombination mit der partiellen Anwendung wäre so knapp wie eine integrierte Version.

+0

Von Interesse: [Drucken formatiertes Datum in F #] (http : //stackoverflow.com/questions/30590473/how-to-print-formatted-date-in-f/30593441#30593441) –

Antwort

1

Dies funktioniert, aber es sollte einen einfacheren Weg geben.

let thousands(x:int64) = 
    System.String.Format("{0:#,0}", x) 

let s = sprintf "%s" (thousands(0L)) 
printfn "%s" s 

let s = sprintf "%s" (thousands(1L)) 
printfn "%s" s 

let s = sprintf "%s" (thousands(1000L)) 
printfn "%s" s 

let s = sprintf "%s" (thousands(1000000L)) 
printfn "%s" s 

0 
1 
1,000 
1,000,000 

Eine etwas bessere Version

let printNumber (x : int) : string = 
    System.String.Format("{0:N0}",x) 
+0

Sorry, das ist Betrug. Ich suche nach einer Antwort, die nicht auf String.Format angewiesen ist. Mit anderen Worten, nur sprintf, nicht .NET Framework-Bibliotheken. Danke fürs ausprobieren. –

+4

Erstens gibt es keine Möglichkeit, dies mit F # Formatspezifizierern zu tun. Zweitens, entschuldigen Sie die Enttäuschung, aber die F # -Format-Funktionen verwenden unten .NET FW-Bibliotheken, insbesondere 'TextWriter'. Und mit dem Formatbezeichner '% t' oder'% a' können Sie direkt in den zugrundeliegenden TextWriter einhaken. –

2

Da Sie nicht tun können, dass mit dem Printf-Modul, das tue ich es wie folgt aus:

/// Calls ToString on the given object, passing in a format-string value. 
let inline stringf format (x : ^a) = 
    (^a : (member ToString : string -> string) (x, format)) 

Und dann es so nennen:

someNumber |> stringf "N0" 
+0

Das ist interessant, aber ich denke, ich kann den "X Prize" nicht vergeben, da die Verwendung von ToString nicht besser ist als die Verwendung von String.Format. Ich konnte Ihre Lösung im folgenden Beispiel verwenden und ToString direkt im OO-Modus aufrufen. Aber ich bin immer noch ein F # Anfänger, also bin ich sehr verwirrt wegen deiner Syntax. Ich kenne 'a (einen allgemeinen Wert), aber was ist^a? Vielen Dank! lassen Sie x = 42345 |> stringf "N0" // -> val x: string = "42,345" lassen Sie x '= 44325L.ToString ("N0") // -> val x': string = " 44.325 " –

+1

Die Inline-Funktion mit dem'^a' kann man sich im Grunde als Duck-Typing vorstellen. In diesem Fall funktioniert die Funktion 'stringf' mit jedem Objekt, das über eine' ToString'-Methode verfügt, die eine Zeichenfolge als Eingabe akzeptiert und eine Zeichenfolge zurückgibt. Wenn Sie versuchen, es mit einem Objekt zu verwenden, das diese Überladung für ToString nicht aufweist, erhalten Sie einen Compiler-Fehler. Mit anderen Worten, 'stringf' ist eine funktionale Methode zum Aufrufen von' ToString (string) 'genauso wie die eingebaute 'string'-Funktion eine funktionale Methode ist,' ToString() 'aufzurufen. Soweit "nicht besser als mit String.Format" was lässt dich denken, dass es ein besseres gibt? –

+1

Technisch ist es ein 'Member Constraint Invocation Expression'. Es ist in [F # spec] (http://fsharp.org/specs/language-spec/) beschrieben. – kaefer

Verwandte Themen