Ken
Ken

Reputation: 382

Take next parameter as field width in String.Format

In C#, I have a width I want to use for some strings, but I won't know that width until runtime. I'm doing something like this:

string.Format("{0, " + digits + "}", value)  // prints 123 as "  123"

Is there a string formatting directive that lets me specify this without smashing my own format string together like this?

I looked around on MSDN for a little while and I feel like I'm missing a whole chapter on format strings or something.

Upvotes: 7

Views: 4429

Answers (8)

Chakrava
Chakrava

Reputation: 883

String has a constructor that creates a string with a given character repeated n times.

https://msdn.microsoft.com/en-us/library/xsa4321w(v=vs.110).aspx

// prints 123 as "  123"
string.Format(new string(' ', digits) + "{0}", value)

Upvotes: 0

Jesse Chisholm
Jesse Chisholm

Reputation: 4026

I posted a CodeProject article that may be what you want.

See: A C# way for indirect width and style formatting.

Basically it is a method, FormatEx, that acts like String.Format, except it allows for indirect alignment and formatString specifiers.

FormatEx("{0,{1}:{2}}", value, width, formatString);

Means format the value of varArgs 0, in a field width specified by varArgs 1, using a formattingString code specified by varArgs 2.

Edit: Internally, it does what many others have suggested in their answers. I've just wrapped the parsing and determination of the final values to use for alignment and formatString. I also added a "center alignment" modifier.

-Jesse

Upvotes: 0

egrunin
egrunin

Reputation: 25053

The functions mentioned by others will work, but this MSDN page has a more general solution to formatting that changes at runtime:

Composite Formatting

They give examples much like yours.

Edit: I thought you were trying to solve the general case of composing a format string at runtime. For example, if there were no built in PadLeft(), you could do this:

    int myInt = 123;
    int nColumnWidth = 10;

    string fmt = string.Format("Price = |{{0,{0}}}|", nColumnWidth);

    // now fmt = "Price = |{0,5}|"

    string s = string.Format(fmt, myInt);

You can even do all that in one line, but it's ugly:

    string s = string.Format(
            string.Format("Price = |{{0,{0}}}|", nColumnWidth),
            myInt);

Upvotes: 2

João Angelo
João Angelo

Reputation: 57688

Probably overkill but just to illustrate a way to encapsulate the format specification and use an overload of String.Format that accepts an IFormatProvider.

class Program
{
    public static void Main(string[] args)
    {
        int digits = 7;
        var format = new PaddedNumberFormatInfo(digits);
        Console.WriteLine(String.Format(format, "{0}", 123));
    }
}
class PaddedNumberFormatInfo : IFormatProvider, ICustomFormatter
{
    public PaddedNumberFormatInfo(int digits)
    {
        this.DigitsCount = digits;
    }

    public int DigitsCount { get; set; }

    // IFormatProvider Members
    public object GetFormat(Type formatType)
    {
        if (formatType == typeof(ICustomFormatter))
            return this;

        return null;
    }
    // ICustomFormatter Members
    public string Format(string format, object arg, IFormatProvider provider)
    {
        return String.Format(
            String.Concat("{0, ", this.DigitsCount, "}"), arg);
    }
}

Upvotes: 0

cpkilekofp
cpkilekofp

Reputation: 101

Perhaps this will help with your research on formatting:

Formatting Types
Composite Formatting

However, I don't think you're going to do much better than this, as the alignment parameter must be part of the format string and does not seem to be represented by a property.

Upvotes: 0

Michael Bray
Michael Bray

Reputation: 15265

Take a look at PadLeft:

s = "123".PadLeft(5);  // Defaults to spaces
s = "123".PadLeft(5, '.');  // Pads with dots

Upvotes: 10

BFree
BFree

Reputation: 103740

You can use the PadLeft and PadRight methods:

http://msdn.microsoft.com/en-us/library/system.string.padleft%28VS.71%29.aspx

Upvotes: 4

Stan R.
Stan R.

Reputation: 16065

you can do something like

string test = valueString.PadLeft(10,' ');

or even sillier

string spaces = String.Concat(Enumerable.Repeat(" ", digits).ToArray());

Upvotes: 3

Related Questions