Mathematica has no real sprintf- or fprintf-equivalents. Others have asked about the problem.
- Can StringTemplate be extended to offer printf-like formatting capabilities?
- sprintf() or close equivalent, or re-implementation?
We can, however, simulate sprintf format with Mathematica functions and a bit of manipulation. Here are some sample values to demonstrate the problems with direct use of NumberForm.
samples = {1.123, 12.12345, -12.12345, 123.12345,
1234.12345, -123.12345, -123.123455};
This is the expected result for samples using sprintf and %9.5f format.
1.123 " 1.12300"
12.12345 " 12.12345"
-12.12345 "-12.12345"
123.12345 "123.12345"
1234.12345 "1234.12345"
-123.12345 "-123.12345"
-123.123455 "-123.12346"
Let's try to create the same result in Mathematica. Unfortunately, NumberForm does not duplicate sprintf.
numberform =
ToString@NumberForm[#, {9, 5}, NumberPadding -> {" ", "0"}] & /@ samples;
The length of the NumberForm strings is 11, but the length of sprintf strings is 9 before overflow. A fix is to trim one or two leading blanks from the NumberForm strings with StringTrim. Here's a comparison of sprintf, using NumberForm alone, and combining StringTrim[#, RegularExpression["^ {1,2}"]] with NumberForm.
sprintf NumberForm StringTrim
" 1.12300" " 1.12300" " 1.12300"
" 12.12345" " 12.12345" " 12.12345"
"-12.12345" " -12.12345" "-12.12345"
"123.12345" " 123.12345" "123.12345"
"1234.12345" " 1234.12345" "1234.12345"
"-123.12345" " -123.12345" "-123.12345"
"-123.12346" " -123.12346" "-123.12346"
To simulate how fprintf would work with some sample data, first, convert the floating-point values in y to sprintf format. Convert the value in d to a string with ToString[IntegerPart[d[[i]]]]. Next, separate the sprintf strings with comma and a space: ", ". Here are some sample values for y and d.
SeedRandom[1]
y = RandomReal[{-99, 99}, {1, 4}];
d = RandomInteger[10, 4];
i = 1;
floats = StringTrim[#, RegularExpression["^ {1,2}"]] & /@
(ToString@NumberForm[#, {9, 5}, NumberPadding -> {" ", "0"}] & /@
y[[i]]);
s = StringJoin[
Riffle[Flatten@{floats, ToString[IntegerPart[d[[i]]]]}, ", "]
];
s // InputForm
The result, s, simulates the output of sprintf("%9.5f, %9.5f, %9.5f, %9.5f, %d", ...).
" 62.84312, -76.93892, 57.32615, -61.81498, 3"
Finally, save the formatted values to a text file.
Export[SystemDialogInput["FileSave", "fname.txt"], s]