C#中的十进制后缀打印出意外值

时间:2018-05-19 16:29:25

标签: c# decimal string-formatting currency-formatting

以下初始化......

Account account1 = new Account("Jane Green", 50.00m);

...在运行我编写的相关测试类时,应该渲染一个控制台行......

Jane Green's balance: €50,00

...根据本书和我从中复制的测试类(书中说$ 50,00,但由于选择了语法,请进一步了解,控制台应该以欧元写入)

相反,它给了我一行:

Jane Green's balance: 50,00 ?

通过存款账户方法向账户添加资金时也会出现同样的情况,即使它因为线路而应该以欧元确认...

Console.WriteLine($"{account1.Name}'s balance: {account1.Balance:C}");

它顽固地印刷......

Jane Green's balance: 75,00 ?

我通过调整我的PC的区域和键盘设置来搜索解决方案,因为我怀疑这是问题的一部分但无济于事(我住在比利时,所以Azerty kb(逗号间隔)和欧元&# 39; s代表货币)

有谁能告诉我如何让它写出正确的输出?

2 个答案:

答案 0 :(得分:1)

根据the docs,格式化的字符串输出将为50,00 €(而不是您预期的€50,00)。但是,控制台未正确显示欧元字符 - 它正在替换为?

您可以使用Console.OutputEncoding = Encoding.UTF8;

解决此问题

答案 1 :(得分:1)

Console.OutputEncoding设置为UTF8解决问题的第一部分:

using System.Text;
// ...
Console.OutputEncoding = Encoding.UTF8;

现在您可以将这些替代品用于欧元符号(比利时):


选项1 :更改默认格式。这会影响您的所有代码。

using System.Globalization;
// ...
CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture("nl-be");
Console.WriteLine($"Jane Green's balance: {50.00m:C}");


选项2 :在使用C#' s字符串插值之前,将数字格式化为字符串。

CultureInfo culture = CultureInfo.CreateSpecificCulture("nl-be");
Console.WriteLine($"Jane Green's balance: {50.00m.ToString("C2", culture)}");


选项3 :将您的字符串用作FormattableString和预定义的文化:

CultureInfo culture = CultureInfo.CreateSpecificCulture("nl-be");
Console.WriteLine(((FormattableString)$"Jane Green's balance: {50.00m:C}").ToString(culture));

以上所有选项都为您提供:

  

Jane Green的余额:50,00€



什么是明确的 - 你想要的是什么

如果您需要:

  

Jane Green的余额:€50,00

然后您应该首先定义自定义格式提供程序:

NumberFormatInfo numberFormat = new NumberFormatInfo()
{
    CurrencySymbol = "€",
    CurrencyDecimalDigits = 2,
    CurrencyDecimalSeparator = ",",
    CurrencyGroupSeparator = ".",
    CurrencyGroupSizes = new int[] { 3 }, // https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.currencygroupsizes(v=vs.110).aspx
    CurrencyNegativePattern = 12, // https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.currencynegativepattern(v=vs.110).aspx
    CurrencyPositivePattern = 2, // https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.currencypositivepattern(v=vs.110).aspx
};


选项4 :将FormattableString与您的自定义格式一起使用。

Console.WriteLine(
    ((FormattableString)$"Jane Green's balance: {50.00m:C}").ToString(numberFormat) );


选项5 :创建一个方便的帮助器类,用于在将字符串打印到控制台之前格式化字符串。

public static class Log
{
    static Log() { Console.OutputEncoding = Encoding.UTF8; }

    public static IFormatProvider CustomFormat =
        new NumberFormatInfo() { ... };

    public static void WriteLine(FormattableString str)
    {
        Console.WriteLine(str.ToString(CustomFormat ?? CultureInfo.CurrentCulture));
    }
}

//...

Log.WriteLine($"Jane Green's balance: {50.00m:C}");
Log.CustomFormat = ...


另请参阅Language & Country Codes列表。