1

I have to manage a particular string formatting/padding condition. To be short I need to pad a string argument only if the argument length is 0. If I use the typical aligment parameter the padding is made if the length of the argument is smaller then the provided alignment value. For example:

string format = "#{0,10}#";
string argument;
string output;

argument = Console.ReadLine();

output = String.Format(format, argument);

String.WriteLine(output);

If I enter "try" as a value I got this result:

#try        #

If I enter "trytrytrytry" I got:

#trytrytrytry#

What I would like to happen is depicted below: Entering "" I would like to have:

#          #

but entering "try" I would like to have:

#try#

The code I'm going to write should be as much generic as possibile since the format parameter is not static and is defined at runtime.

The best practice to do this is to define a custom string formatter. Unluckly it seems that the customization code can only act on the 'format' portion of the format parameter of the String.Format() method.

Indeed If I define a custom formatter:

public class EmptyFormatter : IFormatProvider, ICustomFormatter
{
     public object GetFormat(Type formatType)
     {
         if (formatType == typeof(ICustomFormatter))
             return this;
         else
             return null;
     }

     public string Format(string format, object arg, IFormatProvider formatProvider)
     {
         if (!this.Equals(formatProvider))
             return null;

         if (string.IsNullOrEmpty(format))
             throw new ArgumentNullException();

         return numericString;
     }
 }

The format and arg parameters of the Format method didn't contain the alignment parameter then I cannot actually check what lenght of the padding value should be applied and therefore I cannot act properly. Moreover this part of the 'formatting' of the string seems to be applied somewhere else but I have not idea where.

Is there a way to 'alter' this behaviour ?

6
  • Your description of the problem doesn't really make sense. Why does "" produce 11 spaces? Commented Dec 13, 2015 at 13:36
  • if you check arg for String.Empty you can output 11 spaces else you handle the default. Commented Dec 13, 2015 at 13:38
  • @DavidG it was a typo... it was mean to have 10 spaces... Commented Dec 13, 2015 at 13:39
  • So you either want 10 spaces or the value of arg? Why a custom formatter for this and not just use an if statement? Commented Dec 13, 2015 at 13:40
  • @rene that's the point... I don't know if I have to pad for 10 (or 11 or one billion white spaces) prior to the run of the code.. the format parameter is taken from outside. Commented Dec 13, 2015 at 13:42

1 Answer 1

1

A format item has the following syntax:

index[,alignment][ :formatString] }

The reason the format parameter is null is because there is no formatString component, there is only alignment. I couldn't find a way to access the alignment component from the Format method. However, one (ugly) solution is to set the formatString to be the same as the alignment, so that you can access it using the format parameter:

#{0,10:10}#

A less ugly solution would be to create your own method extension that first extracts the alignment from the given format and then calls the traditional String.Format method.

For example:

    public static string StringFormat(this string Arg, string Format) {
        //extract alignment from string
        Regex reg = new Regex(@"{[-+]?\d+\,[-+]?(\d+)(?::[-+]?\d+)?}");

        Match m = reg.Match(Format);
        if (m != null) { //check if alignment exists
            int allignment = int.Parse(m.Groups[1].Value); //get alignment
            Arg = Arg.PadLeft(allignment); //pad left, you can make the length check here
            Format = Format.Remove(m.Groups[1].Index - 1, m.Groups[1].Length + 1); //remove alignment from format
        }


        return (string.Format(Format, Arg));
    }

To use the code:

string format = "#{0,10}#";
string argument = "try";
string output = argument.StringFormat(format); //"#       try#"
Sign up to request clarification or add additional context in comments.

3 Comments

Uhm this, second, sounds like a good solution. Do you have an example reference ?
Altough the second solution would be the 'best' solution I would lean to parse the whole format parameter lookling for 'aligment' param.. that's exactly what I was trying to avoid... I think I will switch on your first proposal.
I have added an example, although I'm not sure if that regex passes all cases.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.