2017-07-26 10 views
5

Próbuję uzyskać dane wejściowe od użytkownika, przeanalizować je, a następnie wyświetlić za pomocą String.Format(), formatując tysiące z comas.C# Konwertuj ciąg znaków na podwójny/dziesiętny i z powrotem na ciąg, utrzymując końcowe zera, dodając comas dla tysięcy

So, if user provides 
1000 I will display 1,000 
1000.00 => 1,000.00 
1000.0 => 1,000.0 
1,000.5 => 1,000.5 

Zasadniczo chcę zachować wszystkie dziesiętne (w tym końcowe zera), które zostały dostarczone i po prostu dodać formatowanie dla tysięcy. Próbowałem:

String.Format("{0:#,0.######}" , Decimal.Parse(input)); 
String.Format("{0:#,0.######}" , Double.Parse(input); 

Odpowiedz

7

double.Parse(input) to nie idź, jak double nie śledzić liczbę miejsc po przecinku.

decimal.Parse(input).ToString() pokaże, że decimal śledzi to. Niestety, decimal.Parse(input).ToString() używa tej precyzji i nie używa separatora tysięcy, a decimal.Parse(input).ToString("N") ignoruje precyzję, ale używa separatora tysięcy.

Ręcznie wydobywania precyzja z przecinku działa, choć i który pozwala zbudować poprawny format ciąg:

static string InsertThousandsSeparator(string input) { 
    var dec = decimal.Parse(input); 
    var bits = decimal.GetBits(dec); 
    var prec = bits[3] >> 16 & 255; 
    return dec.ToString("N" + prec); 
} 

ta opiera się na the layout of decimal as described on MSDN:

Bity 16 do 23 muszą zawierać wykładnik między 0 a 28, który wskazuje potęgę 10, aby podzielić liczbę całkowitą.

See it working on .NET Fiddle. (dzięki uprzejmości @Alisson)

+0

To wszystko, wszystkie przypadki testowe minęły (sam testowałem). Ładne i czyste rozwiązanie. – Alisson

+0

Doskonały. Wielkie dzięki. Myślałem, że będę musiał napisać Regex, którego bardzo lubię unikać. – Razkar

-1

Jeśli nie przeszkadza 1000 konwertowane do 1,000.00 następnie po to najlepszy, jaki uzna za locale użytkownika zbyt.

string output = String.Format("{0:n}", input); 

Jeśli chcesz 1000 przekształca się tylko 1000, a następnie można użyć następujących:

string output2 = String.Format("{0:#,##0.##}", input); 
+0

"Jeśli nie masz nic przeciwko 1000 konwersji na 1000,00" - Jeśli nie masz nic przeciwko ignorowaniu tego, co jest w pytaniu, każda odpowiedź działa, ale pytanie to konkretnie omawia. – hvd

+0

Nie o to prosił OP. Chcą zachować tę samą liczbę miejsc dziesiętnych. – Alisson

+0

Zgadzam się, zła odpowiedź bez właściwego przeczytania pytania. Mój błąd. – Sach

0

Można użyć wyrażenia regularnego do tego:

var input = "1000.50000"; 
var regex = new Regex("^(?<int>-?[\\d,]+)\\.(?<fract>\\d+)$"); 
var match = regex.Match(input); 
var integralPart = match.Groups["int"].Value.Replace(",", ""); 
var fractionalPart = match.Groups["fract"].Value; 
var result = $"{decimal.Parse(integralPart):n0}.{fractionalPart}"; 
0
 public string DoFormat(string num) 
    { 
     int pt = num.IndexOf("."); 
     if (pt > 0) 
     { 
      return string.Format("{0:#,##0}", num.Substring(0, pt)) + num.Substring(pt, num.Length - pt); 
     } 
     else 
     { 
      return string.Format("{0:#,##0}", num); 
     } 
    } 

to rozdzielenie ciąg znaków w przecinku dziesiętnym i zwraca to, co jest po kropce dziesiętnej, jak zostało wpisane w BUT formatuje całkowitą część liczby z przecinkami.