# sprintf() or close equivalent, or re-implementation?

Is there a sprintf() command (some command that takes a printf-style format string and a list of values to insert into the string) or something very much like it (preferably with a similar style of format specifiers)? Or, alternately, how would I implement sprintf() in Mathematica?

-

I've had a need for such a function several times, and I found this implementation of C-style *printf functions, by Vlad Seghete. To use it, all you need to do is extract the files to \$UserBaseDirectory/MathPrintF/ and you're all set.

Here's an example once you've installed it:

<<MathPrintF
sprintf["%d %s %d %s, %s %s %s %s",
Sequence @@ Riffle[{1, 2, "red", "blue"}, {"fish"}, {2, -1, 2}]]

Out[1]= 1 fish 2 fish, red fish blue fish


Also note the following caveat in the README

## Limited Functionality

While we tried to mimic the C-standard as much as possible, only certain features are implemented. These are mainly dictated by what we needed at the time. In particular %d, %f, %e, %E and %s with most of their options are implemented.

-

Not as such. The closest equivalent is StringForm, but it doesn't provide the formatting options that the printf family does. StringForm gets a lot of use in the creation of messages.

Example:

StringForm["The value of Pi is ", NumberForm[N[Pi], 3]]

(* ==>  "The value of Pi is 3.14" *)


Note that StringForm does not create a string, it merely displays with a special formatting. It can easily be converted to the equivalent string using ToString@StringForm[...] though.

-
Yes, the formatting has to be done on the control string and parameter strings themselves. E.g., StringForm["1 is in InputForm, while 2 is in TraditionalForm, you see!", InputForm[Exp[x]], TraditionalForm[Exp[x]]]. –  Ｊ. Ｍ. Jan 30 '12 at 1:50
@J.M. exactly. (You need a longer name to allow all of us to enter very short responses to your nuggets of wisdom. And, why yes, I'm intentionally leaving an extra long comment just because.) –  rcollyer Jan 30 '12 at 2:19
I thought an example would be in order, please review my edit. –  Szabolcs Jan 30 '12 at 9:46
@Szabolcs, works for me. –  rcollyer Jan 30 '12 at 10:58

Mathematica does not have a built-in equivalent to sprintf. The closest thing is StringForm which allows placeholders within a string to be replaced, but does not perform any formatting of the replacement values:

sprintf[control_, args___] := StringForm[control, args] // ToString

sprintf["hello, ", "Joe"]
(* "hello, Joe" *)


It is not pretty, but we could use JLink to access Java's printf-like formatting syntax:

Needs["JLink"]
jsprintf[control_, args___] :=
JavaBlock @ Module[{jArgs, array}
, jArgs = MakeJavaObject @ N @ # & /@ {args}
; array = JavaNew["[Ljava.lang.Object;", Length@jArgs]
; MapIndexed[javalangreflectArrayset[array, #2[[1]]-1, #1]&, jArgs]
; javalangStringformat[control, array]
]

jsprintf["Hello, %s: Pi is %16.14f", "Joe", Pi]
(* "Hello, Joe: Pi is 3.14159265358979" *)

-

The simple (e.g. non-tabular, no-formatting) case would look something like this.

mmaSprintf[s : {__String}, d_?VectorQ] /; Length[d] == Length[s] :=
StringJoin[Riffle[Riffle[s, ToString /@ d], " "]]


Message has a syntax similar to sprintf() but not the formatting capabilities. From the documentation:

rsqrt::nnarg = "The argument 1 is not greater than or equal to zero.";
Message[rsqrt::nnarg, x]

-

As already mentioned before StringForm together with ToString can give functionality that is provided by sprintf in other languages.

Here are some examples that might be useful and avoid any funny mathematica escape sequences in the strings:

myStrings = {
ToString[StringForm["This is a floating point: 1\n" ,
ToString[NumberForm[5.6 10^9, NumberFormat -> (SequenceForm[#1, "e", #3] &)]]
]],

ToString[StringForm["This is a integer in blocks : 1\n" ,
ToString[NumberForm[10^9, DigitBlock -> 3]]
]],

ToString[StringForm["This is a number with funny padding : 1 " ,
ToString[NumberForm[6.888, {7, 3}, NumberPadding -> {"_", "0"}]]
]],

ToString[StringForm["This is just a string : 1 " , "FOO"]]
};
myCompleteString = StringJoin[myStrings]

FullForm[myCompleteString]

Export["text.txt", myCompleteString, "Text"]


this will give you:

This is a floating point: 5.6e9
This is a integer in blocks : 1,000,000,000
This is a number with funny padding : ____6.888 This isjust a string : FOO

"This is a floating point: 5.6e9\nThis is a integer in blocks : 1,000,000,000\nThis is a number with funny padding : ____6.888 This is just a string : FOO "


and a file text.txt with the expected output.

I believe SequenceForm has been superseded by Row`. –  Sjoerd C. de Vries Sep 27 at 10:54