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).
Related
I'm new to the C#/MVC world. I spend a lot of time today figuring out how to display a DateTimeOffset object in the format i want. Finally got it working this way.
Html.TextBoxFor(model => model.DeliveryDate,"{0:MM/dd/yyyy}",
new { htmlAttributes = new { #class = "datepicker" } })
But I still don't understand the importance of '0' in the format string. the page breaks if i replace the 0 with any other number or totally remove it. Can someone help me understand this?
From String.Format Method
The {0} in the format string is a format item. 0 is the index of the object whose string value will be inserted at that position. (Indexes start at 0.) If the object to be inserted is not a string, its ToString method is called to convert it to one before inserting it in the result string.
That's a format string with parameters (like used in e.g. Console.WriteLine, or string.Format). The {0} would be the placeholder for the first argument, and {0:mm/dd/yyyy} is simply a format string to convert the first argument to a string.
When you use the string.Format you can pass the space for arguments like {0}, {1}, etc which is the indexes you pass as arguments for the method. It is the same for asp.net razor helpers.
You also can provide the format after the index separating by :, for sample: {0:0.00} as format for a number with 2 decimals places or {1:dd/MM/yyyy} for dates etc.
String Interpolation
There is a new way to implement it using the String Interpolation. Basically, you can concat the values on your string without generating new strings. For sample:
var i = 18;
var s = $"You are {age} years old.";
Since you start the string with $, you can pass arguments between { and }. You also can use the same formats to format your data as you use on string.Format. For sample:
var today = $"Today is {DateTime.Now:D}";
var date = DateTime.Now.Add(1);
var tommorrow = $"Tommorrow is {date:dd/MM/yyyy}";
See the documentation for String.Format():
https://msdn.microsoft.com/en-us/library/system.string.format.aspx
In a nutshell, when the model is rendered to HTML text, the DeliveryDate object value will be passed to String.Format(), where {0} indicates the index of the first value in an array of values being passed to Format(). So {0:MM/dd/yyyy} just means to format the first value in the array using date components. Basically, it will do something like this internally:
String s = SomeValueArray[0].ToString("MM/dd/yyyy");
0 is a placeholder for your argument / property (in this case) DeliveryDate.. Similar to String.Format examples... so when your View is rendered.. the 0 will be replaced with whatever value that DeliveryDate is holding in the format MM/dd/yyyy
I have a number value in string as
string strNum = "12345678.90";
I want to format it with comma separator using regex in String.Format()
On using "{0:n0}" format in
String.Format("{0:n0}", Convert.ToDouble(strNum));
it is giving me output as "12,345,679"
Instead of this i want output as "1,23,45,678.90". After thousand's place i want comma separator after 2 digits each for lakhs, crores and so on
How can this be achieved?
var s = String.Format(new CultureInfo( "en-IN", false ), "{0:n}", Convert.ToDouble("12345678.90"));
For such a typical way I would write a specialized function that transforms a number into the string you propose.
I even would suggest to make the item a class, having the value represented as float or by different items like lakhs, crores etc.
And then make a ToString method to output it the way you want.
Example (not tested):
class SpecialNumber
{
int _lakhs;
int _crores;
int _another_unit;
int _rest;
public SpecialNumber(int lakhs, int crores, int another_unit, int rest)
{
_lakhs = lakhs;
_crores = crores;
_another_unit = another_unit;
_rest = rest;
}
public string ToString()
{
// Check for exact formatting.
return String.Format("{0:2},{1:2},{2:3}.{0:2}",
_laksh, _crores, _another_unit, _rest);
}
My best bet would be to use the String.Format along with '#' as such:
String.Format(0:##,##,##,##,##,###.##)
The '#' is a digit placeholder and will not show a zero (or anything else) if the number is not large enough.
See MSDN custom numeric format strings for further details.
you seem to format according to hindi culture.
so set your culture, or provide the culture to String.Format, like
String.Format(CultureInfo.GetCultureInfo( "<yourculture>" ), "{0:n}", Convert.ToDouble(strNum));
With this code you can change an amount string to Indian standard comma separated value; use culture "hi-IN" and the format "{0:#,0.00}"
here strNum is my string value amount.
string.Format( System.Globalization.CultureInfo.CreateSpecificCulture("hi-IN"), "{0:#,0.00}", Convert.ToDouble(strNum)
I have a split string,
string s = Console.ReadLine();
string[] values = s.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
s should receive input like this:
string literal, numeric value, numeric value, numeric value OR string literal
I realize that all this input gets read as a string, but I'm trying to validate the numbers in the string (checking for >0), as well as assign each value in the string to a variable. What would be the best way to go about this?
You're looking for a specific pattern. I'd suggest to use a regex, and then get the number groups - and do the > 0 validation check.
string s = Console.ReadLine();
string[] values = s.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
string stringValue0 = values[0];
int numericValue1 = int.Parse(value[1]); // Assuming the value is an valid interger.
int numericValue2 = int.Parse(value[2]); // Assuming the value is an valid interger.
int numericvalue3;
string stringValue3;
if (!int.TryParse(values[3], out numericValue3) // Trying to convert the text to an interger. If it fails, assign it to the stringValue3.
stringValue3 = values[3];
You can always use int.TryParse to validate if a text contains a number.
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 have a numeric string like this 2223,00. I would like to transform it to 2223. This is: without the information after the ",". Assume that there will be only two decimals after the ",".
I did:
str = str.Remove(str.Length - 3, 3);
Is there a more elegant solution? Maybe using another function? -I donĀ“t like putting explicit numbers-
You can actually just use the Remove overload that takes one parameter:
str = str.Remove(str.Length - 3);
However, if you're trying to avoid hard coding the length, you can use:
str = str.Remove(str.IndexOf(','));
Perhaps this:
str = str.Split(",").First();
This will return to you a string excluding everything after the comma
str = str.Substring(0, str.IndexOf(','));
Of course, this assumes your string actually has a comma with decimals. The above code will fail if it doesn't. You'd want to do more checks:
commaPos = str.IndexOf(',');
if(commaPos != -1)
str = str.Substring(0, commaPos)
I'm assuming you're working with a string to begin with. Ideally, if you're working with a number to begin with, like a float or double, you could just cast it to an int, then do myInt.ToString() like:
myInt = (int)double.Parse(myString)
This parses the double using the current culture (here in the US, we use . for decimal points). However, this again assumes that your input string is can be parsed.
String.Format("{0:0}", 123.4567); // "123"
If your initial value is a decimal into a string, you will need to convert
String.Format("{0:0}", double.Parse("3.5", CultureInfo.InvariantCulture)) //3.5
In this example, I choose Invariant culture but you could use the one you want.
I prefer using the Formatting function because you never know if the decimal may contain 2 or 3 leading number in the future.
Edit: You can also use Truncate to remove all after the , or .
Console.WriteLine(Decimal.Truncate(Convert.ToDecimal("3,5")));
Use:
public static class StringExtensions
{
/// <summary>
/// Cut End. "12".SubstringFromEnd(1) -> "1"
/// </summary>
public static string SubstringFromEnd(this string value, int startindex)
{
if (string.IsNullOrEmpty(value)) return value;
return value.Substring(0, value.Length - startindex);
}
}
I prefer an extension method here for two reasons:
I can chain it with Substring.
Example: f1.Substring(directorypathLength).SubstringFromEnd(1)
Speed.
You could use LastIndexOf and Substring combined to get all characters to the left of the last index of the comma within the sting.
string var = var.Substring(0, var.LastIndexOf(','));
You can use TrimEnd. It's efficient as well and looks clean.
"Name,".TrimEnd(',');
Try the following. It worked for me:
str = str.Split(',').Last();
Since C# 8.0 it has been possible to do this with a range operator.
string textValue = "2223,00";
textValue = textValue[0..^3];
Console.WriteLine(textValue);
This would output the string 2223.
The 0 says that it should start from the zeroth position in the string
The .. says that it should take the range between the operands on either side
The ^ says that it should take the operand relative to the end of the sequence
The 3 says that it should end from the third position in the string
Use lastIndexOf. Like:
string var = var.lastIndexOf(',');