3

This seems like a really dumb problem, but I just haven't managed to get around it. Here is the code:

private string[] ConvertToCurrency(string[] costs)
{
    int count = costs.Length;

    for (int i = 0; i < count - 1; i++)
    {
        costs[i] = String.Format("{0:C}", costs[i]);
    }

    return costs;
}

and I expect that the output should be the numbers I'm storing in my string array will be formatted to currency, but they're completely unchanged when they come out the other end.

I have no idea why this is happening, and have tried some other methods to format it but nothing.

1
  • 6
    Why does the for-loop terminate at count-1 instead of count? Commented Nov 2, 2012 at 8:24

5 Answers 5

12

You should do this, {0:C} is for currency format and it will apply to a numeric value.

costs[i] = String.Format("{0:C}", Convert.ToDecimal(costs[i]));
Sign up to request clarification or add additional context in comments.

Comments

5

Full explanation:

When you have an item like {0:C} in your string, then the C part is a format string. To quote the documentation:

If formatString is present, the argument referenced by the format item must implement the IFormattable interface (my emphasis)

An IFormattable object like double or decimal has an overload of ToString that takes in a string, which could then be "C" in your case. So it translates to something like yourFormattableThing.ToString("C", null).

However, when you look at the documentation for string, you see that a string (like your costs[i]) is not IFormattable, and a string does not possess a ToString that takes in a format string. So you are violating the "must implement" from my quote above.

Instead of raising an exception, String.Format chooses to ignore your C part.

So there's your explanation of what's going wrong.

Now, to make things work, if your string is really a number, convert/parse it to an IFormattable object like decimal or double, and then use the "C" format string on the numeric type.

Comments

0

It is because parameter string[] costs type is string so it will not format the number as you expect. You have to change the parameter type to number (int, long, float, double, etc) or you have to convert the value to numeric type before you format it.

var val = Convert.ToInt32(costs[i]);
costs[i] = String.Format("Value is: {0:C}", val);

Comments

0
public static class StringExtensions
{
    /// <summary>
    /// Formats a string using the string.Format(string, params object[])
    /// </summary>
    /// <param name="helper">The string with the format.</param>
    /// <param name="args">The value args.</param>
    /// <returns>The formatted string with the args mended in.</returns>
    public static string Mend(this string helper, params object[] args) => string.Format(helper, args);

}

// Usage: "Zero: {0}, One: {1}, Two: {2}".Mend("0", "1", "2");

Comments

-1

Building on the previous answers this seems like the perfect place to introduce linq:

private IEnumerable<String> ConvertToCurrency(IEnumerable<String> costs)
{
 return costs.Select(c => String.Format("{0:C}", Convert.ToDecimal(c)));
}

So in this case it will still work on arrays in exactly the same way, but makes the logic accessible to Lists/Queue's etc... If you want to eager execute add a ToArray() after the select.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.