Search code examples
c#string-formatting

Dynamic size text columns formatting


I'm rewriting an old tool (which I don't have the original code) and one of the features is to print a list with filenames which his ID.

My goal is to get this result:

0     0x1A00000F
AAAAAAAAAAA         0x1A00000C
AAAAAAAAAAAAAAAAAAAA              0x1A000007
BBBBBBBBBBBBBBBBBBBBBBBBB         0x1A00000D
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 0x1A00000D
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC              0x1A00000E

but I'm getting this result:

0                   0x1A00000F
AAAAAAAAAAA         0x1A00000C
AAAAAAAAAAAAAAAAAAAA0x1A000007
BBBBBBBBBBBBBBBBBBBBBBBBB0x1A00000D
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB0x1A00000D
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0x1A00000E

The idea is to do this using string format, but the result is not the expected one, the code I'm using is this one:

for(int i = 0; i < files.Length; i++)
{
    string FileLabel = files[i];
    ws.WriteLine("{0,-14}{1}", FileLabel, GetHexNumber(0x1A000000 + i));
}

The idea is to use whitespace between the "part A" and "part B", not tabs. The original tool that prints this list seems that his logic is that when the part A is one character away from reaching part B adds 14 whitespaces, but not sure how can I do this, or if I can do it with string.format.

How can I get this result?


Solution

  • Since the second column always starts at 14n + 6 characters for some integer n, we can subtract 6 from the length of the string in the first column, find the smallest multiple of 14 that is strictly greater than that, and add the 6 back. This gives us where the second column should start.

    string Format(string col1, string col2) {
        var padLength = NextMultipleOf14(col1.Length - 6) + 6;
        return col1.PadRight(padLength) + col2;
    }
    
    int NextMultipleOf14(int x) {
        if (x < 0) return 0;
        if (x % 14 == 0) return x + 14;
        return x + (14 - x % 14);
    }
    

    Usage:

    // assuming GetHexNumber returns a string
    Format(FileLabel, GetHexNumber(0x1A000000 + i))