C#中decimal.ToString("C")输出带问号的货币格式问题排查
问题:C#控制台中decimal.ToString("C")输出末尾带问号的原因及解决办法
问题描述
在C#控制台应用中,使用decimal类型的ToString("C")货币格式时,输出末尾始终带有问号?,更换不同的CultureInfo或省略该参数都无法解决;但使用无格式符的默认ToString()时,问号消失。相关代码及输出如下:
代码片段
sb .Append("Fastest Release: ") .Append(TimeSpan.FromSeconds(fastestReleaseSeconds)) .Append(Environment.NewLine) .Append("Average Release Time: ") .Append(TimeSpan.FromSeconds(avgReleaseSeconds)) .Append(Environment.NewLine) .Append("Slowest release: ") .Append(TimeSpan.FromSeconds(slowestReleaseSeconds)) .Append(Environment.NewLine); sb .Append("Total Euro value of Base Currency at engage: ") .Append(totValueOfBaseAtEngage.ToString("C", CultureInfo.CurrentCulture)) .Append(Environment.NewLine) .Append("Total current Euro value of base currency: ") .Append(totCurrentEuroValueOfBase.ToString("C", CultureInfo.CurrentCulture)) .Append(Environment.NewLine); sb .Append("Total Euro value of Quote Currency at engage: ") .Append(totValueOfQuoteAtEngage.ToString("C", CultureInfo.CurrentCulture)) .Append(Environment.NewLine) .Append("Total current Euro value of quote currency: ") .Append(totCurrentEuroValueOfQuote.ToString("C", CultureInfo.CurrentCulture)) .Append(Environment.NewLine);
异常输出
建仓时基础货币的总欧元价值: 2.300,00 ?
基础货币当前总欧元价值: 2.208,48 ?
建仓时报价货币的总欧元价值: -2.300,00 ?
报价货币当前总欧元价值: -2.385,44 ?
原因分析
这个问号是控制台输出编码不支持当前文化的货币符号导致的:
- 使用
"C"格式时,ToString会生成包含对应文化货币符号的字符串(比如欧元符号€); - 控制台默认的输出编码(如Windows系统默认的OEM编码、GBK等)无法识别欧元符号这类Unicode字符,会将其替换为问号
?; - 默认
ToString()不包含货币符号,因此不会出现该问题。
解决方案
方案1:修改控制台输出编码为UTF-8
在程序启动时添加以下代码,强制控制台使用UTF-8编码输出,同时确保控制台字体支持显示欧元符号(如Consolas、微软雅黑):
Console.OutputEncoding = System.Text.Encoding.UTF8;
方案2:自定义格式,手动添加货币符号
如果不需要依赖系统文化的货币符号,可以使用数值格式"N2"(保留两位小数),再手动拼接欧元符号:
// 示例:替代原ToString("C", ...)的写法 totValueOfBaseAtEngage.ToString("N2") + " €"
方案3:修改控制台系统默认编码
在Windows控制台中执行命令切换到UTF-8编码:
chcp 65001
也可以通过控制台属性,将默认编码设置为UTF-8(需重启控制台生效)。
内容的提问来源于stack exchange,提问作者AlessandroParma
相关产品推荐
相关产品推荐

