c# How to separate an int with decimal points? - c#

I am trying to format an int with decimal points as separators, not commas.
Example: 1234567890 should be formatted to 1.234.567.890
text_team1.text = em.team1Score.ToString("#,##0");
This will give 1,234,567,890
However in this topic there was some information about using the class CultureInfo which contains the format-style, so I used several of them:
text_team1.text = em.team1Score.ToString("#,##0", new System.Globalization.CultureInfo("IS-is"));
as an example. But it seems that every cultureInfo uses a comma as separator.
Even by editing the string afterwards, there is still the comma as seperator.
text_team1.text = em.team1Score.ToString("#,##0");
text_team1.text.Replace(',','.');

Even by editing the string afterwards, there is still the comma as
seperator.
text_team1.text = em.team1Score.ToString("#,##0");
text_team1.text.Replace(',','.');
You forgot to assign the replaced string back.
text_team1.text = text_team1.text.Replace(',','.');
EDIT:
If you still prefer a solution without using the Replace function, you can use the Extension method below. It works for strings and ints. Please Google and read about extension methods if you don't know how they work.
Create and place the ExtensionMethod script in any folder in your project:
using System.Globalization;
using System;
public static class ExtensionMethod
{
public static string formatStringWithDot(this string stringToFormat)
{
string convertResult = "";
int tempInt;
if (Int32.TryParse(stringToFormat, out tempInt))
{
convertResult = tempInt.ToString("N0", new NumberFormatInfo()
{
NumberGroupSizes = new[] { 3 },
NumberGroupSeparator = "."
});
}
return convertResult;
}
public static string formatStringWithDot(this int intToFormat)
{
string convertResult = "";
convertResult = intToFormat.ToString("N0", new NumberFormatInfo()
{
NumberGroupSizes = new[] { 3 },
NumberGroupSeparator = "."
});
return convertResult;
}
}
Usage:
string stringToFormat = "1234567890";
Debug.Log(stringToFormat.formatStringWithDot());
Or
int intToFormat = 1234567890;
Debug.Log(intToFormat.formatStringWithDot());
Or
string stringToFormat = "1234567890";
text_team1.text = stringToFormat.formatStringWithDot();
Use each one depending on which scenario you run into.

If you are using globalisation as a means to format your string, you could set a Custom Group Seperator
NumberFormatInfo nfi = new CultureInfo( "en-US", false ).NumberFormat;
// Displays the same value with a blank as the separator.
Int64 myInt = 1234567890;
nfi.NumberGroupSeparator = ".";
Console.WriteLine( myInt.ToString( "N0", nfi ) );
https://dotnetfiddle.net/vRqd6x

I prefer using string.Format().
Does your OS represent numbers with that format? If so, you can try with the simplest form
text_team1.text = string.Format("{0:N}", em.team1Score);
or you can force it with
text_team1.text = string.Format(CultureInfo.GetCultureInfo("IS-is"), "{0:N}", em.team1Score);
which cares of the culture.

Related

Get Exact format string with respect to given format specifier

There are lot of format specifier in .net e.g. C for currency, D for decimal.
Lot of defined formats can be here.
How can I get exact format behind format specifier as per given locale.
E.g. (I assume here en-US locale)
GetFormatSpecifierText("C") should return me "$" #,##0.00
GetFormatSpecifierText("F") should return me "#,##0.00
Look at how Culture is used in combination with the format specifiers. I believe you may be looking for the override in the below code from MSDN:
public class userOverrideSample
{
[WebMethod]
public String UserLocalSetting()
{
int i = 100;
// Sets the CurrentCulture to French in France.
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
// Displays i formatted as currency for the CurrentCulture.
// Due to operating system differences, you cannot be sure what currency
// symbol will be used.
return (i.ToString("c"));
}
[WebMethod]
public String OverrideUserSetting()
{
int i = 100;
// Sets the CurrentCulture to French in France.
// Uses the CultureInfo constructor that takes a
// useUserOverride parameter.
// Sets the useUserOverride value to false.
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR", _
false);
// Displays i formatted as currency for the CurrentCulture.
// This will override any user settings and display the euro symbol.
return (i.ToString("c"));
}
}
I write below code to get currency format pattern.
Here, passed param numberFormat as [Currency]#,##0.00 and fr-FR locale; and got # ##0,00 "€" as desire and expected o/p.
static string[] CurrencyPositivePattern = { "$n", "n$", "$ n", "n $" };
static string[] CurrencyNegativePattern = { "($n)", "-$n", "$-n", "$n-", "(n$)",
"-n$", "n-$", "n$-", "-n $", "-$ n",
"n $-", "$ n-", "$ -n", "n- $", "($ n)",
"(n $)" };
internal static string GetCurrencyPattern(System.Globalization.NumberFormatInfo numberFormatInfo, string numberFormat)
{
numberFormat = numberFormat.Replace("[Currency]", string.Empty);
int pos = numberFormatInfo.CurrencyPositivePattern;
int neg = numberFormatInfo.CurrencyNegativePattern;
string currencySymbol = string.Format("\"{0}\"", numberFormatInfo.CurrencySymbol);
string excelPattern = string.Concat(CurrencyPositivePattern[pos].Replace("n", numberFormat).Replace("$", currencySymbol),
";",
CurrencyNegativePattern[neg].Replace("n", numberFormat).Replace("$", currencySymbol));
return excelPattern;
}
Few References that I used for implementation:
https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.currencynegativepattern(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.currencypositivepattern(v=vs.110).aspx
As I stucked at specific Currency format for excel, I write Currency specific code. Others formats are easily handled by excel (same also commented by Murray Foxcroft in answer's comment).

custom string format 0,0 with slash or back slash

i have a WPF TextBox that user can type number in that . now i am searching for a string format that can separate TextBox number each 3 point (like 0,0) but i want separate text with Slash or Back Slash or another character. and we do not know how many point our number has.
i am searching for string format not Linq solution or etc . i read Microsoft help but cant find any way .
sample = 123456789 == > 123/456/789 (good) --- 123,456,789 (bad)
Update :
Thanks guys but i search for some thing like this stringformat= {}{0:0,0} etc . i mean dont want use string function like regex , replace or linq or any c# code . i want use a string like {#,#} or etc. see microsoft link in my post i need create a string for my issue.
As the OP insists on the use of String.Format:
string input; //the input of your textbox
int temp = int.Parse(input); //parse your input into an int
//the Format() adds the decimal points, the replace replaces them with the /
string output = String.Format("{0:0,0}", temp).Replace('.', '/');
The important step here is to cast the text of your textbox into an integer, as this simplifies the insertion of the decimal points with String.Format().
Of course, you have to make sure that your textbox is a valid number upon parsing or you may get an exception.
EDIT
So... you have some dynamic-length number and want to format it using a static format-string (as regexes, string replaces, ling or any c# code at all (!) are a no go)? This is impossible.
You HAVE TO have some dynamic code creating a format string somewhere.
Without referencing to regexes or string replaces again, here is some code to create a format string depending on your input number.
This way you have just one String.Format() call. Perhaps you can put the algorithm to create the format string somewhere else and just call it from whereever you need it.
string input; //the input of your textbox
int temp = int.Parse(input); //parse your input into an int
string customString = "{0:";
string tempS = "";
for (int i = 0; i < input.Length; i++)
{
if (i % 3 == 0 && i != 0)
{
tempS += "/";
}
tempS += "#";
}
tempS = new string(tempS.Reverse().ToArray());
customString += tempS;
customString += "}";
string output = String.Format(customString, temp));
You can use a custom NumberFormatInfo. Then use it for ToString with the "n"-format specifier:
NumberFormatInfo nfi = (NumberFormatInfo)CultureInfo.InvariantCulture.NumberFormat.Clone();
nfi.NumberGroupSeparator = "/";
nfi.NumberDecimalDigits = 0; // otherwise the "n" format specifier adds .00
Console.Write(123456789.ToString("n", nfi)); // 123/456/789
You can use NumberFormatInfo.NumberGroupSeparator Property
Sample from MSDN
using System;
using System.Globalization;
class NumberFormatInfoSample {
public static void Main() {
// Gets a NumberFormatInfo associated with the en-US culture.
NumberFormatInfo nfi = new CultureInfo( "en-US", false ).NumberFormat;
// Displays a value with the default separator (",").
Int64 myInt = 123456789;
Console.WriteLine( myInt.ToString( "N", nfi ) );
// Displays the same value with a blank as the separator.
nfi.NumberGroupSeparator = " ";
Console.WriteLine( myInt.ToString( "N", nfi ) );
}
}
/*
This code produces the following output.
123,456,789.00
123 456 789.00
*/
for you - set NumberGroupSeparator property to '/'
UPDATE
another sample
var t = long.Parse("123/456/789",NumberStyles.Any, new NumberFormatInfo() { NumberGroupSeparator = "/" });
var output = string.Format(new NumberFormatInfo() { NumberGroupSeparator="/"}, "{0:0,0}", t);

why my parsed Double value is not right?

Im trying to parse a string to a Double.
Here is My code:
string a = "10.23";
double b = Double.Parse(a);
but b is 1023.0 and I dont know why. I would like to get 10.23 as a Double
It's because of your culture settings, you may specify culture for Parse method to get desired output:
string a = "10.23";
double b = double.Parse(a, System.Globalization.CultureInfo.InvariantCulture);
// b == 10.23
In Germany the comma (,) is used as the decimal point, whereas most English cultures and your example use the full stop (.) as the decimal point. Since Double.Parse uses the thread default culture to parse numbers, and the thread default culture is set to German, you're getting the wrong result.
You should instead specify the culture explicitly:
using System.Globalization;
string a = "10.23";
double b = Double.Parse(a, CultureInfo.InvariantCulture);
The invariant culture uses the full stop as the decimal point, so I suggest you use that instead. Or if you get the string from a source known to be written using a particular cultural convention, use that culture instead.
Or your location for number formatted, try this my source:
Ext:
public static class Ext
{
public static double? AsLocaleDouble(this string str)
{
var result = double.NaN;
var format = Thread.CurrentThread.CurrentUICulture.NumberFormat;
double.TryParse(str, NumberStyles.AllowDecimalPoint, format, out result);
return result;
}
}
Test:
class Program
{
static void Main(string[] args)
{
var str = "10,23";
Thread.CurrentThread.CurrentUICulture = new CultureInfo("uz-Cyrl-UZ");
Thread.CurrentThread.CurrentCulture = new CultureInfo("uz-Cyrl-UZ");
Console.WriteLine(str.AsLocaleDouble());
Console.ReadKey();
}
}

Parsing formatted string

I am trying to create a generic formatter/parser combination.
Example scenario:
I have a string for string.Format(), e.g. var format = "{0}-{1}"
I have an array of object (string) for the input, e.g. var arr = new[] { "asdf", "qwer" }
I am formatting the array using the format string, e.g. var res = string.Format(format, arr)
What I am trying to do is to revert back the formatted string back into the array of object (string). Something like (pseudo code):
var arr2 = string.Unformat(format, res)
// when: res = "asdf-qwer"
// arr2 should be equal to arr
Anyone have experience doing something like this? I'm thinking about using regular expressions (modify the original format string, and then pass it to Regex.Matches to get the array) and run it for each placeholder in the format string. Is this feasible or is there any other more efficient solution?
While the comments about lost information are valid, sometimes you just want to get the string values of of a string with known formatting.
One method is this blog post written by a friend of mine. He implemented an extension method called string[] ParseExact(), akin to DateTime.ParseExact(). Data is returned as an array of strings, but if you can live with that, it is terribly handy.
public static class StringExtensions
{
public static string[] ParseExact(
this string data,
string format)
{
return ParseExact(data, format, false);
}
public static string[] ParseExact(
this string data,
string format,
bool ignoreCase)
{
string[] values;
if (TryParseExact(data, format, out values, ignoreCase))
return values;
else
throw new ArgumentException("Format not compatible with value.");
}
public static bool TryExtract(
this string data,
string format,
out string[] values)
{
return TryParseExact(data, format, out values, false);
}
public static bool TryParseExact(
this string data,
string format,
out string[] values,
bool ignoreCase)
{
int tokenCount = 0;
format = Regex.Escape(format).Replace("\\{", "{");
for (tokenCount = 0; ; tokenCount++)
{
string token = string.Format("{{{0}}}", tokenCount);
if (!format.Contains(token)) break;
format = format.Replace(token,
string.Format("(?'group{0}'.*)", tokenCount));
}
RegexOptions options =
ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None;
Match match = new Regex(format, options).Match(data);
if (tokenCount != (match.Groups.Count - 1))
{
values = new string[] { };
return false;
}
else
{
values = new string[tokenCount];
for (int index = 0; index < tokenCount; index++)
values[index] =
match.Groups[string.Format("group{0}", index)].Value;
return true;
}
}
}
You can't unformat because information is lost. String.Format is a "destructive" algorithm, which means you can't (always) go back.
Create a new class inheriting from string, where you add a member that keeps track of the "{0}-{1}" and the { "asdf", "qwer" }, override ToString(), and modify a little your code.
If it becomes too tricky, just create the same class, but not inheriting from string and modify a little more your code.
IMO, that's the best way to do this.
It's simply not possible in the generic case. Some information will be "lost" (string boundaries) in the Format method. Assume:
String.Format("{0}-{1}", "hello-world", "stack-overflow");
How would you "Unformat" it?
Assuming "-" is not in the original strings, can you not just use Split?
var arr2 = formattedString.Split('-');
Note that this only applies to the presented example with an assumption. Any reverse algorithm is dependent on the kind of formatting employed; an inverse operation may not even be possible, as noted by the other answers.
A simple solution might be to
replace all format tokens with (.*)
escape all other special charaters in format
make the regex match non-greedy
This would resolve the ambiguities to the shortest possible match.
(I'm not good at RegEx, so please correct me, folks :))
After formatting, you can put the resulting string and the array of objects into a dictionary with the string as key:
Dictionary<string,string []> unFormatLookup = new Dictionary<string,string []>
...
var arr = new string [] {"asdf", "qwer" };
var res = string.Format(format, arr);
unFormatLookup.Add(res,arr);
and in Unformat method, you can simply pass a string and look up that string and return the array used:
string [] Unformat(string res)
{
string [] arr;
unFormatLoopup.TryGetValue(res,out arr); //you can also check the return value of TryGetValue and throw an exception if the input string is not in.
return arr;
}

Format a double value like currency but without the currency sign (C#)

I feed a textbox a string value showing me a balance that need to be formatted like this:
###,###,###,##0.00
I could use the value.ToString("c"), but this would put the currency sign in front of it.
Any idea how I would manipulate the string before feeding the textbox to achieve the above formatting?
I tried this, without success:
String.Format("###,###,###,##0.00", currentBalance);
Many Thanks,
If the currency formatting gives you exactly what you want, clone a NumberFormatInfo with and set the CurrencySymbol property to "". You should check that it handles negative numbers in the way that you want as well, of course.
For example:
using System;
using System.Globalization;
class Test
{
static void Main()
{
NumberFormatInfo nfi = CultureInfo.CurrentCulture.NumberFormat;
nfi = (NumberFormatInfo) nfi.Clone();
Console.WriteLine(string.Format(nfi, "{0:c}", 123.45m));
nfi.CurrencySymbol = "";
Console.WriteLine(string.Format(nfi, "{0:c}", 123.45m));
}
}
The other option is to use a custom numeric format string of course - it depends whether you really want to mirror exactly how a currency would look, just without the symbol, or control the exact positioning of digits.
string forDisplay = currentBalance.ToString("N2");
Have you tried:
currentBalance.ToString("#,##0.00");
This is the long-hand equivalent of:
currentBalance.ToString("N2");
string result=string.Format("{0:N2}", value); //For result like ### ### ##.##
You can do this with the group separator and the section separator, like this:
currentBalance.ToString("#,0.00;(#,0.00)");
This does not account for culture variances like the answer from #JonSkeet would, but this does mimic decimal place, rounding, thousands separation, and negative number handling that en-US culture currency format produces using a single custom format string.
.NET Fiddle Demo
var result = currentBalance.ToString("C").Replace(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.CurrencySymbol, "");
CultureInfo cultureInfo = new CultureInfo("en-US");
cultureInfo.NumberFormat.CurrencySymbol = "Rs.";
Thread.CurrentThread.CurrentCulture = cultureInfo;
decimal devimalValue = 3.45M;
this.Text = devimalValue.ToString("C2"); //Rs.3.45
This may be overkill, but it rounds, formats...
#helper TwoDecimalPlaces(decimal? val)
{
decimal x = 0;
decimal y = 0;
string clas = "text-danger";
if (val.HasValue)
{
x = (decimal)val;
if (val > 0)
{
clas = "";
}
}
y = System.Math.Round(x, 2);
IFormatProvider formatProvider = new System.Globalization.CultureInfo(string.Empty);
<span class="#clas">#string.Format("{0:N2}", y)</span>
}
This simple solution works for me with US currency.
If not needing international currency support use this and replace the $ with the currency symbol(s) to be removed:
// for USD
string result = currentBalance.ToString("C").Replace("$", "")
or
// for EUR
string result = currentBalance.ToString("C").Replace("€", "")

Categories