Search code examples
c#.netstring.format

How to pad right with zeros using string.format while using dynamic formats?


I have the illustrative code below. I need the output for condition1 to be right justified and padded with zeros like |1234500000| instead of |0000012345| instead of and with fixed width of 10. The format string is conditional meaning there can be one of many possible format strings depending on some criteria while there's only one line for output. Therefore functions like PadRight and PadLeft can't be used with value unless there's a way to use them while still having the same output line. (.NET 4.5)

How can I get |1234500000| while satisfying those requirements?

string format;

if (condition1)
format = "|{0:0000000000}|";
else
if (condition2)
format = "|{0}|";
//more conditions here
Int64 value = 12345;
string a = String.Format(format, value);
a.Dump();

Solution

  • There are only so many built-in and customizable string formats. Perhaps you could set up a different formatting function for each condition, then invoke it later:

    Func<Int64, String> formatter;
    if (condition1) 
    {
        formatter = (number) => number.ToString().PadRight(10, '0');
    }
    else if (condition2) 
    {
        formatter = (number) => number.ToString();
    }
    
    Int64 sample = 12345;
    string output = string.Format("|{0}|", formatter(sample));
    output.Dump();
    

    Another option would be to create your own custom string format providers by implementing IFormatProvider and ICustomFormatter. For example, here's a sloppy one that would do the right padding:

    public class RightPaddedStringFormatter : IFormatProvider, ICustomFormatter
    {
        private int _width;
    
        public RightPaddedStringFormatter(int width) 
        {
            if (width < 0)
                throw new ArgumentOutOfRangeException("width");
    
            _width = width;
        }
    
        public string Format(string format, object arg, IFormatProvider formatProvider)
        {
            // format doubles to 3 decimal places
            return arg.ToString().PadRight(_width, '0');
        }
    
        public object GetFormat(Type formatType)
        {
            return (formatType == typeof(ICustomFormatter)) ? this : null;
        }
    }
    

    Then you could use your conditions to pick a formatter, e.g.:

    IFormatProvider provider;
    if (condition1)
    {
        provider = new RightPaddedStringFormatter(10);
    }
    ...
    
    Int64 sample = 12345;
    string output = string.Format(provider, "|{0}|", sample);
    output.Dump();