1

I have a Powershell output to re-format, because formatting gets lost in my StandardOutput.ReadToEnd().
There are several blanks to be removed in a line and I want to get the output formatted readable. Current output in my messageBox looks like

Microsoft.MicrosoftJigsaw     All
Microsoft.MicrosoftMahjong     All

What I want is

Microsoft.MicrosoftJigsaw     All
Microsoft.MicrosoftMahjong    All

What am I doing wrong?
My C# knowledge still is basic level only

I found this question here, but maybe I don't understand the answer correctly. The solution doesn't work for me.
Padding a string using PadRight method

This is my current code:

string first = "";
string last = "";
int idx = line.LastIndexOf(" ");
if (idx != -1)
    {
     first = line.Substring(0, idx).Replace(" ","").PadRight(10, '~');
     last = line.Substring(idx + 1);
    }
MessageBox.Show(first + last);
phuzi
  • 12,078
  • 3
  • 26
  • 50
Mahobo
  • 105
  • 1
  • 16
  • 1
    The argument of PadRight (10) is the size of the complete line. The length of `Microsoft.MicrosoftJigsaw` is way longer. – Jeroen van Langen Jan 23 '19 at 13:56
  • Try using 29/30 instead of 10 for padright. – Lasse V. Karlsen Jan 23 '19 at 13:59
  • Can you explain why you believe your program should work, and what you believe it should do? By understanding how your beliefs are wrong, we can better disabuse you of false beliefs. – Eric Lippert Jan 23 '19 at 14:00
  • 1
    you could try inserting a tab into the string instead, this would sort of snap the different words to the same tab locations. `"\t"` is what you should use in the string, so yours would look like `"Microsoft.MicrosoftJigsaw\tAll"` and `"Microsoft.MicrosoftMahjong\tAll"`, sometimes it's necessary to to two tabs which would just be `"\t\t"` – jreese Jan 23 '19 at 14:14
  • I tried 50 instead of 10 now, but as a result, the '~' is being placed right beneath the string 'last', although it should be placed right beneath the string 'first' from my expectation. I'm using the '~' for debugging only. There should be a space instead later. '~' is way better to see. – Mahobo Jan 23 '19 at 14:15
  • first = line.Substring(0, lastIndexOfSpace + 1).Trim().PadRight(totalLength - secondPartLength); last = line.Substring(lastIndexOfSpace + 1).Trim().PadLeft(secondPartLength); – Brijesh Kumar Tripathi Jan 23 '19 at 14:53

3 Answers3

1

The PadRight(10 is not enough, it is the size of the complete string.

I would probably go for something like:

string[] lines = new[] 
{
    "Microsoft.MicrosoftJigsaw     All",
    "Microsoft.MicrosoftMahjong            All"
};

// iterate all (example) lines
foreach (var line in lines)
{
    // split the string on spaces and remove empty ones 
    // (so multiple spaces are ignored)
    // ofcourse, you must check if the splitted array has atleast 2 elements.
    string[] splitted = line.Split(new Char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

    // reformat the string, with padding the first string to a total of 40 chars.
    var formatted = splitted[0].PadRight(40, ' ') + splitted[1];

    // write to anything as output.
    Trace.WriteLine(formatted);
}

Will show:

Microsoft.MicrosoftJigsaw               All
Microsoft.MicrosoftMahjong              All

So you need to determine the maximum length of the first string.

Jeroen van Langen
  • 21,446
  • 3
  • 42
  • 57
1

String.PadLeft() first parameter defines the length of the padded string, not padding symbol count.

Firstly, you can iterate through all you string, split and save.

Secondly, you should get the longest string length.

Finally, you can format strings to needed format.

var strings = new [] 
{
    "Microsoft.MicrosoftJigsaw     All",
    "Microsoft.MicrosoftMahjong     All"
};

var keyValuePairs = new List<KeyValuePair<string, string>>();

foreach(var item in strings)
{
    var parts = item.Split(new [] {" "}, StringSplitOptions.RemoveEmptyEntries);

    keyValuePairs.Add(new KeyValuePair<string, string>(parts[0], parts[1]));
}

var longestStringCharCount = keyValuePairs.Select(kv => kv.Key).Max(k => k.Length);
var minSpaceCount = 5; // min space count between parts of the string

var formattedStrings = keyValuePairs.Select(kv => string.Concat(kv.Key.PadRight(longestStringCharCount + minSpaceCount, ' '), kv.Value));  

foreach(var item in formattedStrings)
{
    Console.WriteLine(item);
}

Result:

Microsoft.MicrosoftJigsaw      All
Microsoft.MicrosoftMahjong     All
Roman
  • 11,966
  • 10
  • 38
  • 47
  • I've tested this solution and it works fine as it is. BUT... I was searching at the wrong end. The problem is, that I'm trying to output the text to a MessageBox (I stated that in my question). The whole problem comes from a non-monospace font. I now use a new form with a textbox as an alternative messagebox. Font is set to Arial Monospaced and all looks great as it should. Thank you all very much for your support! Not sure if I should mark this answer as a solution or answer my own question with what I found out about monospace – Mahobo Jan 24 '19 at 13:25
0

Assuming the length of second part of your string is 10 but you can change it. Try below piece of code:

Function:

private string PrepareStringAfterPadding(string line, int totalLength)
{
    int secondPartLength = 10;
    int lastIndexOfSpace = line.LastIndexOf(" ");
    string firstPart = line.Substring(0, lastIndexOfSpace + 1).Trim().PadRight(totalLength - secondPartLength);
    string secondPart = line.Substring(lastIndexOfSpace + 1).Trim().PadLeft(secondPartLength);
    return firstPart + secondPart;
}

Calling:

    string line1String = PrepareStringAfterPadding("Microsoft.MicrosoftJigsaw     All", 40);
    string line2String = PrepareStringAfterPadding("Microsoft.MicrosoftMahjong     All", 40);

Result:

Microsoft.MicrosoftJigsaw            All
Microsoft.MicrosoftMahjong           All

Note:

Code is given for demo purpose please customize the totalLength and secondPartLength and calling of the function as per your requirement.