I currently use this to format my numbers.
#string.Format("£{0:#,###,###.##}", 1000) outputs £1,000
However when I enter a zero value it does this:
#string.Format("£{0:#,###,###.##}", 0.0) outputs £
How do i make this output even when i enter zero values? e.g £0.0
Thanks
The # character means "only use a digit when you need to".
I suspect you want:
#string.Format("£{0:#,###,##0.##}", value)
However, it would generally be a better idea just to use:
#string.Format("{0:c}", value)
... and let the .NET framework do the right thing.
The first 0 is the placeholder, means the first parameter. 00 is an actual format.
For example it could be like this:
Console.WriteLine(string.Format("£{0:#,###,##0.##}", 0));
Related
I tried to figure out the basics of these numeric string formatters. So I think I understand the basics but there is one thing I'm not sure about
So, for example
#,##0.00
It turns out that it produces identical results as
#,#0.00
or
#,0.00
#,#########0.00
So my question is, why are people using the #,## so often (I see it a lot when googling)
Maybe I missed something.
You can try it out yourself here and put the following inside that main function
double value = 1234.67890;
Console.WriteLine(value.ToString("#,0.00"));
Console.WriteLine(value.ToString("#,#0.00"));
Console.WriteLine(value.ToString("#,##0.00"));
Console.WriteLine(value.ToString("#,########0.00"));
Probably because Microsoft uses the same format specifier in their documentation, including the page you linked. It's not too hard to figure out why; #,##0.00 more clearly states the programmer's intent: three-digit groups separated by commas.
What happens?
The following function is called:
public string ToString(string? format)
{
return Number.FormatDouble(m_value, format, NumberFormatInfo.CurrentInfo);
}
It is important to realize that the format is used to format the string, but your formats happen to give the same result.
Examples:
value.ToString("#,#") // 1,235
value.ToString("0,0") // 1,235
value.ToString("#") // 1235
value.ToString("0") // 1235
value.ToString("#.#")) // 1234.7
value.ToString("#.##") // 1234.68
value.ToString("#.###") // 1234.679
value.ToString("#.#####") // 1234.6789
value.ToString("#.######") // = value.ToString("#.#######") = 1234.6789
We see that
it doesn't matter whether you put #, 0, or any other digit for that matter
One occurrence means: any arbitrary large number
double value = 123467890;
Console.WriteLine(value.ToString("#")); // Prints the full number
, and . however, are treated different for double
After a dot or comma, it will only show the amount of character that are provided (or less: as for #.######).
At this point it's clear that it has to do with the programmer's intent. If you want to display the number as 1,234.68 or 1234.67890, you would format it as
"#,###.##" or "#,#.##" // 1,234.68
"####.#####" or "#.#####" // 1234.67890
We have a requirement to display bank routing/account data that is masked with asterisks, except for the last 4 numbers. It seemed simple enough until I found this in unit testing:
string.Format("{0:****1234}",61101234)
is properly displayed as: "****1234"
but
string.Format("{0:****0052}",16000052)
is incorrectly displayed (due to the zeros??): "****1600005252""
If you use the following in C# it works correctly, but I am unable to use this because DevExpress automatically wraps it with "{0: ... }" when you set the displayformat without the curly brackets:
string.Format("****0052",16000052)
Can anyone think of a way to get this format to work properly inside curly brackets (with the full 8 digit number passed in)?
UPDATE: The string.format above is only a way of testing the problem I am trying to solve. It is not the finished code. I have to pass to DevExpress a string format inside braces in order for the routing number to be formatted correctly.
It's a shame that you haven't included the code which is building the format string. It's very odd to have the format string depend on the data in the way that it looks like you have.
I would not try to do this in a format string; instead, I'd write a method to convert the credit card number into an "obscured" string form, quite possibly just using Substring and string concatenation. For example:
public static string ObscureFirstFourCharacters(string input)
{
// TODO: Argument validation
return "****" + input.Substring(4);
}
(It's not clear what the data type of your credit card number is. If it's a numeric type and you need to convert it to a string first, you need to be careful to end up with a fixed-size string, left-padded with zeroes.)
I think you are looking for something like this:
string.Format("{0:****0000}", 16000052);
But I have not seen that with the * inline like that. Without knowing better I probably would have done:
string.Format("{0}{1}", "****", str.Substring(str.Length-4, 4);
Or even dropping the format call if I knew the length.
These approaches are worthwhile to look through: Mask out part first 12 characters of string with *?
As you are alluding to in the comments, this should also work:
string.Format("{0:****####}", 16000052);
The difference is using the 0's will display a zero if no digit is present, # will not. Should be moot in your situation.
If for some reason you want to print the literal zeros, use this:
string.Format("{0:****\0\052}", 16000052);
But note that this is not doing anything with your input at all.
I am attempting to validate a date text box to make sure the correct date format was entered.
I converted this vb6 code:
If (IsDate(txtBirthDate)) And (IsNumeric(Right(txtBirthDate, 4))))
into this C# code -
int output = 1;
DateTime output2;
if ((! DateTime.TryParse(txtBirthDate.Text, out output2)) & (!int.TryParse((txtBirthDate.Text.Substring(txtBirthDate.Text.Length - 5)), out output)))
{
MessageBox.Show("error")
}
What I am attempting to do is make sure that the last 4 digits of the date text box are numeric (the year - i.e 1990 in 05/10/1990) and if it is not a number, then show error. Although I cannot verify everything is numeric due to the "/" in the date format.
The code does not show an error and builds. But when I debug the application I receive an error. The error states:
Index and length must refer to a location within the string.
Parameter name: length.
Any ideas on how to accomplish this?
To check if a date is in a specific format, use DateTime.TryParseExact():
if (!DateTime.TryParseExact(output , "d/M/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out output2))
{
MessageBox.Show("error")
}
EDIT: Change the format according to your needs:
"d/M/yyyy" for UK and "M/d/yyyy" for US
Edit: It sounds like the cause of your error is your string is too short. Test the string length before you test the last 4 characters.
Three other issues:
The And operator in C# is &&. You are using & which is a bitwise operator.
To check the last four characters of the string, you should use .Length - 4, not 5.
You are negating the return values in your C#, but not in your VB. To match the VB, omit the !. But, it looks like that's not what you are actually trying to do. It looks like you want to show an error message if either the string is not parsable as a date or the year portion is not 4 digits. In that case use a an or comparison (||):
if (!DateTime.TryParse(txtBirthDate.Text, out output2) ||
txtBirthDate.Text.Length < 4 ||
!int.TryParse((txtBirthDate.Text.Substring(txtBirthDate.Text.Length - 4)), out output))
{
MessageBox.Show("error")
}
Keep in mind that yyyy/M/d is also parsable as a Date, contains a 4-digit year, but will fail your test. Is that what you want?
From the error provided it looks like you just need a length check to make sure you can process the code. You should also use && instead of & (or in this case probably ||) to ensure that the boolean expressions stop executing once a true state has been encountered.
if (txtBirthDate.Text.Length < 5 ||
(!DateTime.TryParse(txtBirthDate.Text, out output2) ||
!int.TryParse((txtBirthDate.Text.Substring(txtBirthDate.Text.Length - 5)), out output)))
{
MessageBox.Show("error")
}
However, this might be a good case for the use of a regular expression.
Regex reg = new Regex("^\d{2}/\d{2}/\d{4}$");
if (!reg.IsMatch(txtBirthDate.Text))
MessageBox.Show("error");
Tweaking of the regular expression to match fringe cases (leading zero's, alternate formats, etc) may be necessary.
int result;
if (int.TryParse(txtBirthDate.Text.Substring(test.LastIndexOf("/")), out result))
{
//its good
}
else
{
//its bad
}
I am formatting the currency using Tostring() method i m using following syntax
ToString('##.##') it is working perfectly but in case of round number it remove last 2 zero
like for 100 it does not show 100.00 is shows 100.
how can i format in that way means
input desired output
100 100.00
100.10 100.10
Try "##.00" instead.
That will force two digits after the decimal separator.
You can also use ToString("C") to use the culture specific format in Windows directly.
First google result.
String.Format("{0:C}", x.ToString());
http://www.howtogeek.com/howto/programming/format-a-string-as-currency-in-c/
You can use :
.ToString("C")
Hope it helps.
Also, if you don't want the currency sign ($ in the US) added that "C" gives, you can also use "F2", which is "fixed number with 2 decimal places". It also has the advantage of giving you a thousands separator when you results go over 1,000.00.
This might help. Might be more than you need, but it takes globalization into account which might be necessary. "C" is also a short-cut currency format string that might get you further along.
Is there a way to specify total number of characters when formatting doubles?
Lets say I have 0.00012345678, and I specify total number of characters (7), I want to get 1.23e-4. Format "G7" would give 1.2345e-4.
More examples:
0.00000012345678F -> 1.23e-7
0.00012345678F -> 1.23e-4
0.12345678F -> 1.23e-1
1.2345678F -> 1.23457
12.345678F -> 12.3457
12345678F -> 1.234e8
You probably want to use the "e" format string like so...
String.Format("{0:0.00e+0}", number);
You have a misunderstanding about the meaning of "precision". For a floating point number, "precision" means the number of significant digits, so the result returned by "G6" is correct.
If you want a fixed number of characters, use a custom format string like Jason suggested.
{0:00e+0}
http://blog.stevex.net/string-formatting-in-csharp/