Format text by adding whitespace - c#

I am trying to format strings by whitespaces.
All strings normally look like
01. Anton 30p
02. Cinderella 20p
03. Thomas 18p
04. Anastacia-Laura 16p
I want to format each string, that the points start at the same column.
There I wrote:
s = stringUpToName;
int addSpacing = 37 - s.Length;
for (int i = 0; i < addSpacing; i += 1) s += " ";
s += points;
It gets closer this way, but it's still not perfectly formatted.
I want it to look like this:
01. Anton 30p
02. Cinderella 20p
03. Thomas 18p
04. Anastacia-Laura 16p

Use "0" custom specifier as zero-placeholder symbol to format index/number of record. 0:00 will give you 01 for value 1.
Also keep in mind that item format syntax is { index[,alignment][:formatString]} where alignment indicates preferred formatted field width. So, adding alignment to second item format {1,20} gives you right-aligned field width of 20 characters. With negative alignment field will be left-aligned.
Total format string will look like "{0:00}. {1,-20}{2}p"
You can use it with String.Format or StringBuilder.AppendFormat if you are build string, or Console.WriteLine if you are writing it to console.
int index = 1;
string name = "Anton";
int points = 30;
var result = String.Format("{0:00}. {1,-20}{2}p", index, name, points)
// "01. Anton 30p"

String.Format and Composite Formatting using the Alignment functionality
string[] names = new string[]
{
"1. Anton 30p",
"2. Cinderella 20p",
"3. Thomas 18p",
"4. Anastacia-Laura 16p"
};
foreach(string s in names)
{
int lastSpace = s.LastIndexOf(' ');
int firstSpace = s.IndexOf(' ');
string result = string.Format("{0,-4}{1,-37}{2,4}", s.Substring(0, firstSpace), s.Substring(firstSpace + 1, lastSpace), s.Substring(lastSpace+1));
Console.WriteLine(result);
}
Keep in mind that to see the output exactly aligned in columns you need to use a Fixed Width font like Lucida Console or Courier, because fonts with variable width use less pixel to print an I than to print a W.

Try right-align the numbers using
String.Format("{0} {1} {2,4}p",
Num,
Name,
Point);

Related

What is String Format C# {0,12:N0} (colon and commas) means?

Okay here's the code example:
string header = String.Format("{0,-12}{1,8}{2,12}{1,8}{2,12}{3,14}\n",
"City", "Year", "Population", "Change (%)");
Console.WriteLine(header);
string output;
foreach (var city in cities) {
output = String.Format("{0,-12}{1,8:yyyy}{2,12:N0}{3,8:yyyy}{4,12:N0}{5,14:P1}",
city.Item1, city.Item2, city.Item3, city.Item4, city.Item5,
(city.Item5 - city.Item3)/ (double)city.Item3);
Console.WriteLine(output);
}
}
}
// The example displays the following output:
// City Year Population Year Population Change (%)
//
// Los Angeles 1940 1,504,277 1950 1,970,358 31.0 %
// New York 1940 7,454,995 1950 7,891,957 5.9 %
// Chicago 1940 3,396,808 1950 3,620,962 6.6 %
// Detroit 1940 1,623,452 1950 1,849,568 13.9 %
i understand about the colon after the args {0:N0} means no decimal, but what about the comas? like {0,-12}, and {1,12} what does comma means after the argument of the string format?
MSDN Documentation is your friend (the link I gave in comments above wasn't the best either):
Composite Formatting
Each format item takes the following form and consists of the following components:
{index[,alignment][:formatString]}
So the index is obviously the index of the provided arguments:
String.Format("Second argument = {1}, first argument = {0}", arg1, arg2);
Alignment specifies the desired width of the field and horizontal alignment:
The formatted data in the field is right-aligned if alignment is positive and left-aligned if alignment is negative.
String.Format("{0,-12}" + // first argument, left align, 12 character wide column
"{1,8:yyyy}" + // second argument, right align, 8 character wide column,
// formatted as a year
"{2,12:N0}" + // third argument, right align, 12 character wide column,
// formatted as a number, 0 decimal places
And formatString you already know about (e.g. The Numeric ("N") Format Specifier).
They are index component and alignment component which is part of Composite Formatting. Here is composite formatting syntax;
{index[,alignment][:formatString]}
In your cases, {0,-12} and {1,12}, 0 and 1 are index component which is pointing your first 2 elements that you want to format. And -12 and 12 are alignment components. They can be negative or positive values.
Positive values indicate alignment to the right and negative values indicate alignment to the left.
If you wanna use alignment component, you have to separate it from the index component by a comma. Colon (:) separates alignment component with formatString as you can see on syntax.
Since you use {0,-12} for "Los Angeles" (which is 11 character), it will be aligned with one (12 - 11) white space character to the left.
Console.WriteLine("{0, -12}{1}", "Los Angeles", "1940"); // prints "Los Angeles 1940"
but Chicago (which is 7 character), it will be aligned five (12 - 7) white space character to the left as;
Console.WriteLine("{0, -12}{1}", "Chicago", "1940"); // prints "Chicago 1940"
For positive values;
Console.WriteLine("{0, 12}{1}", "Los Angeles", "1940"); // prints " Los Angeles1940"
but
Console.WriteLine("{0, 12}{1}", "Chicago", "1940"); // prints " Chicago1940"
The Numeric ("N") Format Specifier
The numeric ("N") format specifier converts a number to a string of
the form "-d,ddd,ddd.ddd…", where "-" indicates a negative number
symbol if required, "d" indicates a digit (0-9), "," indicates a group
separator, and "." indicates a decimal point symbol. The precision
specifier indicates the desired number of digits after the decimal
point. If the precision specifier is omitted, the number of decimal
places is defined by the current NumberFormatInfo.NumberDecimalDigits
property.
The result string is affected by the formatting information
of the current NumberFormatInfo object. The following table lists the
NumberFormatInfo properties that control the formatting of the result
string.
For N0 the actual output will no contains digits after the decimal point (like in integer values).
Align numbers with spaces
To align float number to the right use comma „,“ option before the
colon. Type comma followed by a number of spaces, e.g. „0,10:0.0“
(this can be used only in String.Format method, not in double.ToString
method). To align numbers to the left use negative number of spaces.

Show double as percentage without decimals with ToString method

Looking for:
95,4545454545455 -> 95 %
I tried using:
String resultAsPercentage = result.ToString("##0 %");
But, it shows
9545 %
Then, I solved my problem using regex:
Question: Why my ToString method hasn't worked? And how to fix it to avoid using regex?
Thanks in advance.
As documented on Custom Numeric Format Strings, the % modifier multiplies the value by 100 before inserting the %. It's intended to be used with fractions. To disable this special meaning of %, escape it by preceding it with #"\".
Alternatively, you could take the % out of the format string, and append it manually: result.ToString("##0") + " %".
If you don't care about rounding, you can use the following:
double result = 95.4545454545;
String resultAsPercentage = (int)result + " %";
System.out.println(resultAsPercentage);
Output is: 95 %
Casting to an int drops the decimal places without rounding
You can use thew P(ercentage) format specifier, you need to divide through 100 because the specifier multiplies it by 100:
decimal value = 95.4545454545455m;
String resultAsPercentage = (value / 100).ToString("P0"); // 95%
If you need the space between the value and the percentage symbol you could use this approach:
NumberFormatInfo nfi = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone();
nfi.PercentSymbol = " %";
String resultAsPercentage = (value / 100).ToString("P0", nfi); // 95 %
One way can be Clone a culture (like InvariantCulture), set it's PercentPositivePattern to 0, divide your value by 100 and get it's string representation using The percent ("P") format specifier with 0 precision and that cloned culture as;
var clone = (CultureInfo)CultureInfo.InvariantCulture.Clone();
clone.NumberFormat.PercentNegativePattern = 0;
Console.WriteLine(((int)95.4545454545455 / 100.0).ToString("P0", clone)); // 95 %
You can see all associated patterns on Remarks section on that page.
You can guaranteed to set PercentNegativePattern property as well for negative values.

Retain 0 in front of a number

I need help figuring out a logic.
I have a working code where the code will take a string and figure out every numbers in that string then add 1.
string str = "";
str = Console.ReadLine();
str = Regex.Replace(
str,
#"\d+",
m => (Double.Parse(m.Groups[0].Value) + 1).ToString()
);
Example:
If I enter "User 000079 is making $1000 from Jan 02 to Feb 24".
The code will produce output: "User 80 is making $1001 from Jan 3 to Feb 25".
The problem is, I want to keep the 0 in front of the 80 and 3. (i.e. User 000080 is making $1001 from Jan 03 to Feb 25)
How do I do that?
Additional Info: Let me clarify, this is just an example. What I want is just a way to add 1 to every number appearing in the string. So if it means UserID, January 31 - Yes, I still want them to increase by 1
This will do what you need:
string str = Console.ReadLine();
str = Regex.Replace(
str,
#"\d+",
m => (Double.Parse(m.Groups[0].Value) + 1).ToString().PadLeft(m.Groups[0].Value.Length, '0')
);
You can fix this with the ToString format like below:
String x = (50).ToString("D8"); // "00000050"
You can find more info about this here: msdn
edit: About the lengte if you do this the length will be correct:
System.Text.RegularExpressions.Regex.Replace(
str,
#"\d+",
m => (int.Parse(m.Groups[0].Value) + 1).ToString("D" + m.Groups[0].Value.Length)
);
It sounds like your user ID numbers aren't really 'numbers', but rather strings of numeric characters. Can the representation of the ID be changed to a string instead?
If you only care about the extra zeroes when rendering the ID, you can use String.Format to render the numeric value correctly using Custom Numeric Formats (specifically, see the 'Zero Placeholder' section).

Format custom numeric string with fixed character count

I need to convert any number in a fixed format with a fixed amount of characters. Means 1500 and -1.5 or 0.025 need to have the same length. I also have to give the format in this form: Format = "{???}";
When i type Format = "{0000}"; i can limit 1500 to "1500", but -1.5 -> "-0001.5" means i have too much numbers after the point.
Negative sign place can be done with Format = "{ 0.0;-0.0; 0.0}".
How can i fix the count of the numbers for different numbers?
The length of the string doesn't matter, the most important is the equal length.
Examples:
1500 -> " 1500.000" or " 1500"
-1500 -> "-1500.000" or "- 1500" or " -1500"
1.5 -> " 1.500" or " 1.5"
-0.25-> " -0.250" or "- 0.25"
0.00005 -> " 0.000" or " 0"
150000-> " 150000.0" or " 150000"
15000000 " 15000000"
Edit:
I want to Format an y-Axis of a Chart. I can't use something like value.ToString("???") i need to use chartArea.AxisY.LabelStyle.Format = "{???}";
Why don't use formatting? "F3" forces 3 digits after decimal point and PadLeft ensures the overall length
Double value = 1500.0;
// 3 digits after decimal point, 9 characters length
String result = value.ToString("F3").PadLeft(9, ' ');
0 -> 0.000
1500.0 -> 1500.000
-1500.0 -> -1500.000
-0.25 -> -0.250
Another (similar) possibility is String.Format:
Double value = 1500.0;
// Put value at place {0} with format "F4" aligned to right up to 9 symbols
String result = String.Format("{0:9,F4}", value);
Try it > result = Math.Round(yourValue, 3);
Check full reference here !
you cannot achieve this by a simple format function
string result = string.Empty;
var array = dec.ToString().Split('.');
if (dec > 0)
{
result = array[0].PadLeft(9).Remove(0, 9);
if (array.Count() > 1)
{
result += '.' + array[1].PadRight(3).Remove(3);
}
}
else
{
result = "-"+array[0].PadLeft(9).Remove(0, 9);
if (array.Count() > 1)
{
result += '.' + array[1].PadRight(3).Remove(3);
}
}

How to neatly align text in a textbox and keep it when exporting to .txt

I am having a small stupid issue and I was hoping you guys could join in with your experience.
I need a textbox with the following (dynamic) data:
TEXT
TEXT
TEXT
TEXT
_______________________
Name: Amount:
Blah 3
Blahblah 10
_______________________
But the text inside the box is the issue.
So far I am making all this text with a StringBuilder called SB and in the end I set MyTextBox.Text = SB.ToString();
I set the header inside the box like this:
SB.AppendLine("Name\t\Amount:");
I generate the data inside a loop like this:
SB.AppendLine(name + "\t\t" + amount);
But it doesn't align neatly like my example!
If the name is longer than the previous name, the amount will be appear a whole different place on the line - compared to the previous.
Fx. like this:
TEXT
TEXT
TEXT
TEXT
__________________
Navn Antal:
SpecSaver 1
MadEyes 1
Gucci 1
__________________
My first problem: How can I prevent this? What do you usually do when you need a multiline textbox to contain a lot of data.
My second problem: When I export it to a .txt document like this:
using(var text = new StreamWriter("textfile.txt", false))
{
text.Write(SB);
}
It gives yet another version of the data, completely misaligned. It should be identical to the MyTextBox.Text.
First off you'll need to pick a Fixed-Width font for your text box.
Next, you can provide a Padding amount to string.Format()
(or to StringBuilder.AppendFormat)
StringBuilder sb = new StringBuilder();
sb.AppendLine(string.Format("{0, -20}{1, -10}", "Title 1", "Title 2"));
sb.AppendLine(string.Format("{0, -20}{1, -10}", "Val Col 1 A", "Val Col 2 A"));
sb.AppendLine(string.Format("{0, -20}{1, -10}", "Val Col 1 B", "Val Col 2 B"));
Console.WriteLine(sb.ToString());
Results in:
Title 1 Title 2
Val Col 1 A Val Col 2 A
Val Col 1 B Val Col 2 B
Character alignment is achieved with fixed-pitch fonts - select something like courier-new as the font for both textbox and printing.
See string-padding-problem (Maybe your MessageBox is showing variable-pitch font?).
To (incompletely) answer your first question. Rather than using the same number of tabs for each string you need to count the number of characters in the string as it might contain one, two or more "tabs' worth" of extra characters. For example, consider the following two strings:
"Hi"
"Hello there"
If you added the same number of tabs to each of these the second would still be longer, assuming a tab of 4 spaces.
You can do this manually before you start adding tabs and then only add enough tabs to take the length to the desired amount, or you can us the format statement (see the Eoin's answers).
To (perhaps) answer your second question. Having counted the length of the initial text you could add the required number of spaces rather than tabs and then, assuming you've got a non-proportional font, the numbers will always line up.
you could also lookinto the .padleft .padright(int) methods that add spaces to the left or right to help keep things aligned.
You may also lookinto your font Curior is guly but its made so that each charter in takes up the exact same space W M i stuff like that where in other fonts i would take up less space than a W
If it is just numbers, that are causing the spacing issues, figure spaces can right align them correctly.
int bigNumber = 1234;
int smallNumber = 5;
string bigNumberString = bigNumber.ToString();
string smallNumberString = smallNumber.ToString();
// This works only in a TextBox with a monospaced font.
textBox1.Text = string.Format("{0,4}\n{1,4}",
bigNumberString,
smallNumberString);
// This works in TextBoxes with any font.
textBox1.Text = string.Format("{0}\n{1}",
bigNumberString,
smallNumberString.PadLeft(bigNumberString.Length, '\u2007'));

Categories

Resources