C# Console table is not aligned - c#

I managed to make a simple C# table in a console, there are more than enough threads regarding that.
The problem is due to characters having different sizes(for example 'iiiii'(5 chars) is shorter than 'there'(5 chars)) The table will never be aligned.
Is there a way to calculate the real length of the string value in order to tell how many more spaces need to be added to align the shorter string with the rest of the table?
(I tried to visually display it here but it seems that in the font this site is using all characters have an equal size(and/or padding), However, I can send a screenshot)

Instead of trying to manually align the text into columns with arbitrary strings of spaces, you should embed actual tabs (the \t escape sequence) into each output string.
Console.WriteLine("Row1:" + "\t"
+ "iiiiiii" );
Console.WriteLine("Row2:" + "\t"
+ "7 chars" );

If you know console font name and size, you can try to use TextRenderer.MeasureText to get strings widths in pixels. Then add spaces to shorter ones until strings will be aligned.
Of course you will not get precise positioning this way, but probably it will suit your needs.
UPD. You can refer to How to measure the pixel width of a digit in a given font / size (C#) and/or other similar questions for more details.

Related

Aligning string with spaces

Is there a way to perfectly align two strings in C#?
I am trying to align the string "CBI" with "Central Bureau of Investigation" and I want both strings to occupy 35 characters. I use the function
string.Format("{0,-35}", str);
to format both strings. But they do not appear to be aligned properly. Does it have something to do with the font settings?
I have to use these strings in a chart in excel and they have to occupy the same width on the screen
Yes there is PadLeft and PadRight
str.PadLeft(35);
str.PadRight(35);
str = "BBQ and Slaw";
Console.WriteLine(str.PadLeft(15)); // Displays " BBQ and Slaw".
Console.Write(str.PadRight(15)); // Displays "BBQ and Slaw ".
Side Note from documentation:
However, if totalWidth is less than the length of this instance, the method returns a reference to the existing instance
Basically if your length is less than the length of the string then an reference of the existing string is returned
If EvenMcDonnal wishes to include this in an answer I'll gladly remove it from my answer.
You can find a list of MonoSpaced fonts you can use here
I find that I am never satisfied by monospaced fonts, so I use character padding with a micro-space character (about 1 pixel wide) (char)0x200A to line things up. This is especially useful when simulating column alignment with a list of strings. The most flexible method is to use a while loop comparing string pixel widths and adding the space character until the match. I use System.Windows.Forms.TextRenderer.MeasureText() with a NoPadding flag and just to be save, an initial size of int.MaxValue, then check the Width parameter of System.Drawing.Size. If you feed in any Font in the MeasureText constructor, it works with any font.

Console.Write syntax: what does the format string "{0, -25}" mean

I am writing C# code
Console.Write("{0,-25}", company);
In above code what does this "{0,-25}" thing mean?
You mention it's hard to see what it does: that's because it adds spaces and those are difficult to see in the console. Try adding a character directly before and after the output so you can more clearly see the space, like the examples below:
This
Console.WriteLine("[{0, -25}]", "Microsoft"); // Left aligned
Console.WriteLine("[{0, 25}]", "Microsoft"); // Right aligned
Console.WriteLine("[{0, 5}]", "Microsoft"); // Ignored, Microsoft is longer than 5 chars
Will result in this (with spaces)
[Microsoft ]
[ Microsoft]
[Microsoft]
Which looks like this in the console window:
Read about string formatting on MSDN, specifically composite formatting. The '-25;' specifies the alignment component.
Alignment Component The optional alignment component is a signed
integer indicating the preferred formatted field width. If the value
of alignment is less than the length of the formatted string,
alignment is ignored and the length of the formatted string is used as
the field width. The formatted data in the field is right-aligned if
alignment is positive and left-aligned if alignment is negative. If
padding is necessary, white space is used. The comma is required if
alignment is specified.
That 'thing' is a composite formatting string. See the remarks here and this article here.
It is used for alignment.
Check this so that you can get
Console.Write("Company = |{0,-25}|", company);
string company1="ABC Inc";
string company2="XYZ International Inc";
Console.Write("{0,-10}", company1);//o/p [ABC Inc...]
Console.Write("{0,10}", company1);o/p [...ABC Inc]
Console.Write("{0,-10}", company2);o/p [XYZ International Inc]
//In the first Write(),output is LEFT justified in an output field width of 10
//In second Write(), output is RIGHT justified in an output field width of 10
//In the third Write(), output width is ignored , since the company2 name has more than 10 characters.

C# String formatting doesn't line up

I'm trying to build a number of strings that line up nicely, but the formatting isn't working the way I would expect.
If I have:
String.Format("{0,-25}{1,-7}{2,-18}{3,-8}{4,-15}{5,-3}{6,-10}",
i.Name, "Price: ", i.Price.toString(), "Weight: ",
i.Weight.toString() + " lbs", "Quantity:",i.Quantity.toString()));
I would expect to get Name (which is a string) starting at the beginning of the line, then "Price" starting at character 26, and so on. (None of the names are more than 10 characters). Instead, the second column is all over the place depending on the length of name.
I tried this using a StringBuilder as well, with the same result. A number of internet searches are just showing code that looks pretty much the same as what I have, so I'm not sure what's not working.
Edit: fixed typos
I suspect that the problem is the display rather than the strings themselves. These sorts of alignments only work when the font is a monospace font. A monospace font is one in which each character is the same width. There are several of these provided with Windows,Office, Visual Studio. Many people consider "Consolas" to be the best.
I recommend you change the font of whatever control is displaying your data to Consolas.

string formatting and printing

I am trying to align values. I wonder why this happen :
string value = "";
value += string.Format("{0,-10}", "value");
value += string.Format("{0,5}", "value");
value += Environment.NewLine;
value += string.Format("{0,-8}", "val");
value += string.Format("{0,7}", "value");
Print(value);
If i check value before i "Print" it is correct. The result is:
value value
val value
As they should be, but when i print "value" to my printer then they get like this :
value value
val value
I really cant understand why it changes the string when i print the text?
I have tried to use "\t" but my printer dont seem to understand "\t" because the tabs isnt printed out.
Btw: this is just a test code so you could understand the problem that i am having with the real code.
your console uses fixed width fonts where your printer does not (at least by default). So spaces take up less space on your printer and your letters take up more or less space based on their actual width.
This could be caused by a font that uses different character widths. In non-fixed-width fonts, spaces are often narrower than letters and numbers, so it might seem that spaces are missing. Consider using Lucida Console or another fixed-width font.

C#: How do you go upon constructing a multi-lined string during design time?

How would I accomplish displaying a line as the one below in a console window by writing it into a variable during design time then just calling Console.WriteLine(sDescription) to display it?
Options:
-t Description of -t argument.
-b Description of -b argument.
If I understand your question right, what you need is the # sign in front of your string. This will make the compiler take in your string literally (including newlines etc)
In your case I would write the following:
String sDescription =
#"Options:
-t Description of -t argument.";
So far for your question (I hope), but I would suggest to just use several WriteLines.
The performance loss is next to nothing and it just is more adaptable.
You could work with a format string so you would go for this:
string formatString = "{0:10} {1}";
Console.WriteLine("Options:");
Console.WriteLine(formatString, "-t", "Description of -t argument.");
Console.WriteLine(formatString, "-b", "Description of -b argument.");
the formatstring makes sure your lines are formatted nicely without putting spaces manually and makes sure that if you ever want to make the format different you just need to do it in one place.
Console.Write("Options:\n\tSomething\t\tElse");
produces
Options:
Something Else
\n for next line, \t for tab, for more professional layouts try the field-width setting with format specifiers.
http://msdn.microsoft.com/en-us/library/txafckwd.aspx
If this is a /? screen, I tend to throw the text into a .txt file that I embed via a resx file. Then I just edit the txt file. This then gets exposed as a string property on the generated resx class.
If needed, I embed standard string.Format symbols into my txt for replacement.
Personally I'd normally just write three Console.WriteLine calls. I know that gives extra fluff, but it lines the text up appropriately and it guarantees that it'll use the right line terminator for whatever platform I'm running on. An alternative would be to use a verbatim string literal, but that will "fix" the line terminator at compile-time.
I know C# is mostly used on windows machines, but please, please, please try to write your code as platform neutral. Not all platforms have the same end of line character. To properly retrieve the end of line character for the currently executing platform you should use:
System.Environment.NewLine
Maybe I'm just anal because I am a former java programmer who ran apps on many platforms, but you never know what the platform of the future is.
The "best" answer depends on where the information you're displaying comes from.
If you want to hard code it, using an "#" string is very effective, though you'll find that getting it to display right plays merry hell with your code formatting.
For a more substantial piece of text (more than a couple of lines), embedding a text resources is good.
But, if you need to construct the string on the fly, say by looping over the commandline parameters supported by your application, then you should investigate both StringBuilder and Format Strings.
StringBuilder has methods like AppendFormat() that accept format strings, making it easy to build up lines of format.
Format Strings make it easy to combine multiple items together. Note that Format strings may be used to format things to a specific width.
To quote the MSDN page linked above:
Format Item Syntax
Each format item takes the following
form and consists of the following
components:
{index[,alignment][:formatString]}
The matching braces ("{" and "}") are
required.
Index Component
The mandatory index component, also
called a parameter specifier, is a
number starting from 0 that identifies
a corresponding item in the list of
objects ...
Alignment Component
The optional alignment component is a
signed integer indicating the
preferred formatted field width. If
the value of alignment is less than
the length of the formatted string,
alignment is ignored and the length of
the formatted string is used as the
field width. The formatted data in
the field is right-aligned if
alignment is positive and left-aligned
if alignment is negative. If padding
is necessary, white space is used. The
comma is required if alignment is
specified.
Format String Component
The optional formatString component is
a format string that is appropriate
for the type of object being formatted
...

Categories