I'd like to format a number using a run-time supplied format string.
Isn't something like this possible?
string.Format("{0:{1}}",0,"c")
The "c" may change to be any other type of format string. I've tried various combinations but am failing to find the correct one.
This should work:
var s0 = string.Format("{{0:{0}}}", "c");
var s1 = string.Format(s0, 0);
The double { and } is to escape curly braces.
Related
I have as input the string format CST-000000 and an integer with value 1
Upon using
string result = string.Format("CST-000000", 1);
the expected result should be CST-000001 instead of CST-000000
How could i create this string format dynamically?
For example
- CST-000 should produce CST-001
- HELLO000 should produce HELLO001
- CUSTOMER0000 should produce CUSTOMER0001
Assuming that:
You receive your format string from somewhere and you can't control what it looks like
Your format string ends with 1 or more zeros
If the format string is e.g. CST-00000 and your value is 123, you want the result to be CST-00123
You can do something like this:
Inspect your format string, and separate out the stuff at the beginning from the zeros at the end. It's easy to do this with Regex, e.g.:
string format = "CST-000000";
// "Zero or more of anything, followed by one or more zeros at the end of the string"
var match = Regex.Match(format, "(.*?)(0+)$");
if (!match.Success)
{
throw new ArgumentException("Format must end with one or more zeros");
}
string prefix = match.Groups[1].Value; // E.g. CST-
string zeros = match.Groups[2].Value; // E.g. 000000
Once you have these, note the "Zero placeholder" in this list of custom numeric format strings -- you can write e.g. 123.ToString("0000") and the output will be 0123. This lets you finish off with:
int value = 123;
string result = prefix + value.ToString(zeros);
See it on dotnetfiddle
String.Format requires a placeholder {n} with a zero-based argument number. You can also add it a format {n:format}.
string result = String.Format("CST-{0:000000}", 1);
You can also use String interpolation
string result = $"CST-{1:000000}"
The difference is that instead of a placeholder you specify the value directly (or as an expression). Instead of the Custom numeric format string, you can also use the Standard numeric format string d6: $"CST-{1:d6}"
If you want to change the format template dynamically, String.Format will work better, as you can specify the format and the value as separate arguments.
(Example assumes an enum FormatKind and C# >= 8.0)
int value = 1;
string format = formatKind switch {
FormatKind.CstSmall => "CST-{0:d3}",
FormatKind.CstLarge => "CST-{0:d6}",
FormatKind.Hello => "HELLO{0:d3}",
FormatEnum.Customer => "CUSTOMER{0:d4}"
};
string result = String.Format(format, value);
Also note that the value to be formatted must be of a numeric type. Strings cannot be formatted.
See also: Composite formatting
It seems .toString("CST-000"), .toString("HELLO000") and so on, does the trick.
ToString and String.Format can do much more than use predefined formats.
For example :
string result = string.Format("CST-{0:000000}", 1);
string result = 1.ToString("CST-000000");
Should both do what you want.
(Of course you could replace "1" by any variable, even a decimal one).
I have an issue where I need to add two numeric strings "$1,234.56" and "$9,876.54" and get a string "$11,111.10"
I can convert the strings to numbers, perform the addition, but I don't know of a good way to preserve the formatting when I ToString() the result. I can add a couple of if statements along the lines: does the input have dollar sign, decimal point, percent sign and construct the format string accordingly, but this is clunky and will fail if we ever need to support more than one number format.
Does anyone know how to add numeric strings and preserve formatting?
EDIT: To answer the questions. The format of all strings being added at a given time is the same ie: I don't need to worry about adding $ and £ (in fact £ is not currently supported), However, there are several possible formats that are currently supported and more may be added in the future:
$1,234.00; $1,234; 1234; 1,234; 1,234.00; 1234%; 1,234%; 1,234.00%
I would suggest using the first numeric string as a template and create a number format from it:
var posshalves = firstNumericString.Split('.');
var fmthalves = new string[2] { posshalves[0], (posshalves.Length < 2 ? "" : "."+posshalves[1])};
var intfmt = Regex.Replace(fmthalves[0], #"[0-9]", "#");
intfmt = Regex.Replace(intfmt, #"#+", "#");
var decfmt = Regex.Replace(fmthalves[1], "[0-9]", "0");
var format = $"{intfmt}{decfmt}";
I have used interpolated strings for messages containing string variables like $"{EmployeeName}, {Department}". Now I want to use an interpolated string for showing a formatted double.
Example
var aNumberAsString = aDoubleValue.ToString("0.####");
How can I write it as an interpolated string? Something like $"{aDoubleValue} ...."
You can specify a format string after an expression with a colon (:):
var aNumberAsString = $"{aDoubleValue:0.####}";
A colon after the variable specifies a format,
Console.Write($"{aDoubleValue:0.####}");
Or like this:
Console.Write($"{aDoubleValue:f4}");
In C#.Net, here's a simple example of how to format numbers into strings using custom format strings:
(example taken from: http://www.csharp-examples.net/string-format-int/)
String.Format("{0:+### ### ### ###}", 447900123456); // "+447 900 123 456"
String.Format("{0:##-####-####}", 8958712551); // "89-5871-2551"
Is there a way to convert this formatted string back into a long/integer ? Is there someway to do this :
long PhoneNumber = Int32.Parse("89-5871-2551", "{0:##-####-####}");
I saw that DateTime has a method ParseExact which can do this work well. But I did not see any such thing for int/long/decimal/double.
You can regex out all of the non numeric numbers, and what you're left with is a string of numbers that you can parse.
var myPhoneNumber = "89-5871-2551";
var strippedPhoneNumber = Regex.Replace(myPhoneNumber, #"[^\d]", "");
int intRepresentation;
if (Int32.TryParse(strippedPhoneNumber, out intRepresentation))
{
// It was assigned, intRepresentation = 8958712551
// now you can use intRepresentation.
} else {
// It was not assigned, intRepresentation is still null.
}
Well, you can always do
long PhoneNumber = Int32.Parse("89-5871-2551".
Replace(new char[]{'-','+',whatever..}).Trim());
By the way, considering that you're parsing a string received from some IO, I would suggest to use more secure (in terms of conversion) Int32.TryParse method.
The way like you described doesn't actually exist.
Just Regex out all of the non-numeric characters, then parse that string.
I am currently using the following line:
w.Write(DateTime.Now.ToString("MM/dd/yyyy,HH:mm:ss"));
and it gives and output like:
05/23/2011,14:24:54
What I need is quotations around the date and time, the output should look like this:
"05/23/2011","14:24:54"
any thoughts on how to "break up" datetime, and get quotes around each piece?
Try String.Format:
w.Write(String.Format("\"{0:MM/dd/yyyy}\",\"{0:HH:mm:ss}\"", DateTime.Now));
DateTime.Now.ToString("\\\"MM/dd/yyyy\\\",\\\"HH:mm:ss\\\"")
This will do the trick, too.
string format = #"{0:\""MM/dd/yyyy\"",\""HH:mm:ss\""}" ;
string s = string.Format(format,DateTime.Now) ;
as will this:
string format = #"{0:'\""'MM/dd/yyyy'\""','\""'HH:mm:ss'\""'}" ;
string s = string.Format(format,DateTime.Now) ;
and this
string format = #"{0:""\""""MM/dd/yyyy""\"""",""\""""HH:mm:ss""\""""}" ;
string s = string.Format(format,DateTime.Now) ;
The introduction of a literal double quote (") or apostrophe (') in a DateTime or Numeric format strings introduces literal text. The embedded literal quote/apostrophe must be balanced — they act as an embedded quoted string literal in the format string. To get a double quote or apostrophe it needs to be preceded with a backslash.
John Sheehan's formatting cheatsheets makes note of this...feature, but insofar as I can tell, the CLR documentation is (and always has been) incorrect WRT this: the docs on custom date/time and numeric format strings just says that "[any other character] is copied to the result string unchanged.".
string part1 = DateTime.Now.ToString("MM/dd/yyyy");
string part2 = DateTime.Now.ToString("HH:mm:ss");
Console.WriteLine("\""+part1+"\",\""+part2+"\"");
Works just fine. May not be the best way though
I'm not sure about the type of w but if it supports the standard set of Write overloads the following should work.
w.Write(#"""{0}""", DateTime.Now.ToString(#"MM/dd/yyyy"",""HH:mm:ss")));
If not then you can do the following
var msg = String.Format(#"""{0}""", DateTime.Now.ToString(#"MM/dd/yyyy"",""HH:mm:ss"))));
w.Write(msg);
The following version, though obvious, will not work:
w.Write(DateTime.Now.ToString("\"MM/dd/yyyy\",\"HH:mm:ss\""));
This will output:
MM/dd/yyyy,HH:mm:ss
So don't do that.