0

I have found on SO some posts, regarding formatting strings, representing numbers, to have digit group separators, during converting decimals (or other number data types) to string:

how to format 1700 to 1'700 and 1000000 to 1'000'000 in c#?

C#: Formatting Price value string

What if I have these numbers already in string format (have read from a .txt file by StreamReader), but want to have group separators nevertheless (and in string format)?

Is parsing it to decimal and then back to string with needed formatting the most reasonable way in this case?

Community
  • 1
  • 1
rem
  • 16,745
  • 37
  • 112
  • 180

3 Answers3

2

Just out of curiosity I put this method together to see what it would take to add the separators to the string without parsing and formatting:

public static string AddGroupSeparators(string number) {
  int[] sizes = CultureInfo.CurrentCulture.NumberFormat.NumberGroupSizes;
  int pos = number.LastIndexOf(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);
  if (pos == -1) pos = number.Length;
  int sizeIndex = 0;
  while (sizes[sizeIndex] > 0 && pos > sizes[sizeIndex]) {
    pos -= sizes[sizeIndex];
    number = number.Insert(pos, CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator);
    if (sizeIndex < sizes.Length - 1) sizeIndex++;
  }
  return number;
}
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • Thanks for a great example of string manipulation. (and making things even more evident) +1 – rem Jan 21 '10 at 19:51
1

Is parsing it to decimal and then back to string with needed formatting the most reasonable way

Yes. It will be less messy than doing this with string operations.

H H
  • 263,252
  • 30
  • 330
  • 514
1

I thinks other. I have a another way to format string value.
You could check over it:


''' <summary>
''' Parses and formats a string value
''' </summary>
''' <param name="value">The value to check and format</param>
''' <param name="f_bAddGroupSep">Specifies the formater whether adds more group separator to formatted value string</param>
''' <returns></returns>
''' <remarks></remarks>
Private Function ParseValue(ByVal value As String, _
                            Optional ByVal f_bAddGroupSep As Boolean = True) As String
    'If invalid number
    Dim f_decValue As Decimal = 0
    If (String.IsNullOrEmpty(value, StringAction.Trim) _
    OrElse (Not (Decimal.TryParse(Trim(value), NumberStyles.Number, Me.Culture, f_decValue)))) Then Return "0"
    'Trims value
    value = Trim(value)
    'If not negative, remove the negative signal
    If (Not (Me.IsNegative)) Then value = Replace(value, Me.NumberFormat.NegativeSign, vbNullString)
    'Starts formating value
    Dim f_iDecNum As Int32 = 0
    Dim f_decRndValue As Decimal = 0
    Dim f_sNumPat As String = vbNullString
    If (Me.IsDecimal) Then
        'Parses the decimal digits number
        f_iDecNum = Me.NumberFormat.NumberDecimalDigits
        If (Me.DecimalDigits >= 0) Then f_iDecNum = Me.DecimalDigits
        'If the formatted value had the decimal separator signal
        If (IndexOf(value, Me.NumberFormat.NumberDecimalSeparator) >= 0) Then
            value &= New String("0"c, f_iDecNum)

            'Else (If the formatted value did not have the decimal separator signal)
        Else
            value &= String.Concat(Me.NumberFormat.NumberDecimalSeparator, New String("0"c, f_iDecNum))
        End If
        'Prepares the number format pattern
        f_sNumPat = String.Concat("N", Convert.ToString(f_iDecNum))

        'Else
    Else
        'Prepares the number format pattern
        f_sNumPat = "N"
    End If
    Try
        'Casts the string value to decimal
        f_decValue = Convert.ToDecimal(value, Me.Culture)
        'Prepares the rounded decimal value
        f_decRndValue = f_decValue
        Select Case Me.Round
            'Rounds down
            Case Util.NumberFormat.RoundDown
                f_decRndValue = Decimal.Round(f_decValue, f_iDecNum)
                If (f_decRndValue <> f_decValue) Then f_decRndValue = Decimal.Round((f_decValue - Convert.ToDecimal(String.Concat("0", Me.NumberFormat.NumberDecimalSeparator, New String("0"c, f_iDecNum), "5"), Me.NumberFormat)), f_iDecNum)
                'Rounds up
            Case Util.NumberFormat.RoundUp
                f_decRndValue = Decimal.Round(f_decValue, f_iDecNum)
                If (f_decRndValue <> f_decValue) Then f_decRndValue = Decimal.Round((f_decValue + Convert.ToDecimal(String.Concat("0", Me.NumberFormat.NumberDecimalSeparator, New String("0"c, f_iDecNum), "5"), Me.NumberFormat)), f_iDecNum)
                'Rounds by the decimal digits number
            Case Util.NumberFormat.HalfAdjust
                f_decRndValue = Decimal.Round(f_decValue, f_iDecNum)
                'Rounds up
                If (f_decRndValue > f_decValue) Then
                    f_decRndValue = Decimal.Round((f_decValue + Convert.ToDecimal(String.Concat("0", Me.NumberFormat.NumberDecimalSeparator, New String("0"c, f_iDecNum), "5"), Me.NumberFormat)), f_iDecNum)

                    'Else (Rounds down)
                ElseIf (f_decRndValue < f_decValue) Then
                    f_decRndValue = Decimal.Round((f_decValue - Convert.ToDecimal(String.Concat("0", Me.NumberFormat.NumberDecimalSeparator, New String("0"c, f_iDecNum), "5"), Me.NumberFormat)), f_iDecNum)
                End If
        End Select
        'Returns the formatted decimal value
        value = f_decRndValue.ToString(f_sNumPat, Me.Culture)
    Catch ex As Exception
        f_decValue = 0
        f_decRndValue = 0
        value = "0"
    End Try
    Return value
End Function
  • Use properties:
    -----------------
  • Me.IsDecimal: Specifies whether formats string value as decimal number
  • Me.IsNegative: Specifies whether accepts the negative decimal value
  • Me.Culture: Your culture information
  • Me.NumberFormat: The number format information. It is got from Me.Culture (= Me.Culture.NumberFormat)
  • Me.Round: The way to round a decimal (rounds up, round down, or half adjust (rounds by decimal digits))
  • Me.DecimalDigits: The number of the decimal digits
HaiNguyen
  • 11
  • 2