Reputation: 11866
What is the best way to replicate the behaviour of something like this in C#?
// Converts decimal to a 0-padded string with minimum specified width and precision.
sprintf(out, "%0*.*lf", width, precision, decimal);
I had a read of standard, custom and composite format strings, but I can't see any nice way to achieve this.
The reason I ask is that I just came across this ugly snippet in some code I am maintaining where we are required to format a bunch of decimals according to variable widths and precisions as specified by an external interface:
private static String ZEROS = "00000000000000000000000000";
public override string Format(decimal input, int width, int precision)
{
String formatString = ZEROS.Substring(0, width - precision - 1)
+ "." + ZEROS.Substring(0, precision);
return ToDecimal(input).ToString(formatString);
}
and I would like to replace it with someing a little less horrendous.
UPDATE
Since the final answer is buried in comments, here it is:
public override string Format(decimal input, int width, int precision)
{
string.Format("{0," + width + ":F" + precision + "}", input).Replace(" ","0");
}
In my case the input is always positive so this works too:
public override string Format(decimal input, int width, int precision)
{
return input.ToString("F"+precision).PadLeft(width, 0);
}
Upvotes: 3
Views: 602
Reputation: 224857
Something like this:
return input.ToString(new string('0', width) + '.' + new string('0', precision));
?
Edit: acutally, here's a better one:
return input.ToString(new string('0', width - 1).insert(width - precision, '.'));
Upvotes: 1
Reputation: 30580
You could write it like this, generating a standard format string and then using it:
public static string Format(decimal input, int width, int precision)
{
var format = string.Format("{{0,{0}:F{1}}}", width, precision);
// generates (e.g. width=15, precision=5) "{0,15:F5}"
// then format using this and replace padding with zeroes
return string.Format(format, input).Replace(" ", "0");
}
Or instead of calling format twice just concat the format string, depending on your preference:
string.Format("{0," + width + ":F" + precision + "}", input).Replace(" ","0")
You have to replace the spaces afterwards since there's no way to specify the padding character. Alternately you could write your own formatter to pad with a specific character. This works though :)
Edit: This matches the original for all inputs except when precision = 0
. In that case, the original is incorrect, since it counts the decimal point as part of the width even when it isn't present.
Oops: Forgot to check negative numbers.
Here is a simpler version, but have to check if the number is negative to get the padding correct:
public override string Format(decimal input, int width, int precision)
{
var output = input.ToString("F" + precision);
return input < 0
? "-" + output.Substring(1).PadLeft(width, '0')
: output .PadLeft(width, '0');
}
Upvotes: 3
Reputation: 74197
This is about as good as it gets:
public static string double2string( double value , int integerDigits , int fractionalDigits )
{
string decimalPoint = CultureInfo.CurrentUICulture.NumberFormat.NumberDecimalSeparator ;
StringBuilder sb = new StringBuilder() ;
sb.Append('0',integerDigits)
.Append(decimalPoint)
.Append('0',fractionalDigits)
;
return value.ToString( sb.ToString() ) ;
}
Upvotes: 0
Reputation: 1475
I beleive you could just call Decimal.ToString
and pass it a Custom Numeric Format String that you can generate.
Upvotes: -1
Reputation: 19020
Well, one way to get rid of the ZERO
would be
public override string Format(decimal input, int width, int precision)
{
String formatString = new string('0', width - precision - 1)
+ "." + new string('0', precision);
return ToDecimal(input).ToString(formatString);
}
Not sure if you can do much else.
Upvotes: 0