使用C#格式化字符串
intx=16;
decimaly=3.57m;
stringh=String.Format("item{0}sellsat{1:C}",x,y);
Console.WriteLine(h);
item16sellsat¥3.57
也许你的机器上的输出和这个不太一样。这是正常的,本文稍后就会解释这个问题。在我们日常使用中,更多的是使用Console.WriteLine方法来输出一个字符串。其实String.Format和Console.WriteLine有很多共同点。两个方法都有很多重载的格式并且采用无固定参数的对象数组作为最后一个参数。下面的两个语句会产生同样的输出。
Console.WriteLine("Hello{0}{1}{2}{3}{4}{5}{6}{7}{8}",123,45.67,true,'Q',4,5,6,7,'8');
stringu=String.Format("Hello{0}{1}{2}{3}{4}{5}{6}{7}{8}",123,45.67,true,'Q',4,5,6,7,'8');
Console.WriteLine(u);
Hello12345.67TrueQ45678
Hello12345.67TrueQ456782 字符串格式
String.Format和WriteLine都遵守同样的格式化规则。格式化的格式如下:"{ N [, M ][: formatString ]}", arg1, ... argN,在这个格式中:
1) N是从0开始的整数,表示要格式化的参数的个数
2) M是一个可选的整数,表示格式化后的参数所占的宽度,如果M是负数,那么格式化后的值就是左对齐的,如果M是正数,那么格式化后的值是右对齐的
3) formatString是另外一个可选的参数,表示格式代码
argN表示要格式化的表达式,和N是对应的。
如果argN是空值,那么就用一个空字符串来代替。如果没有formatString,那么就用参数N对应的ToString方法来格式化。下面的语句会产生同样的输出:
publicclassTestConsoleApp
{
publicstaticvoidMain(string[]args)
{
Console.WriteLine(123);
Console.WriteLine("{0}",123);
Console.WriteLine("{0:D3}",123);
}
}
123
123123
也可以通过String.Format得到同样的输出。
strings=string.Format("123");
stringt=string.Format("{0}",123);
stringu=string.Format("{0:D3}",123);
Console.WriteLine(s);
Console.WriteLine(t);
Console.WriteLine(u);
(,M)决定了格式化字符串的宽度和对齐方向
(:formatString)决定了如何格式化数据,比如用货币符号,科学计数法或者16进制。就像下面这样:
Console.WriteLine("{0,5}{1,5}",123,456); //右对齐
Console.WriteLine("{0,-5}{1,-5}",123,456); //左对齐
123 456
123 456也可以合并这些表达式,先放一个逗号,再放一个冒号。就像这样:
Console.WriteLine("{0,-10:D6}{1,-10:D6}",123,456);
输出是:
000123 000456
我们可以用这种格式化特性来对齐我们的输出。
Console.WriteLine("n{0,-10}{1,-3}","Name","Salary");
Console.WriteLine("----------------");
Console.WriteLine("{0,-10}{1,6}","Bill",123456);
Console.WriteLine("{0,-10}{1,6}","Polly",7890);
Name Salary
----------------Bill 123456
Polly 7890
3 格式化标识符
字母 | 含义 |
C或c | Currency 货币格式 |
D或d | Decimal 十进制格式(十进制整数,不要和.Net的Decimal数据类型混淆了) |
E或e | Exponent 指数格式 |
F或f | Fixed point 固定精度格式 |
G或g | General 常用格式 |
N或n | 用逗号分割千位的数字,比如1234将会被变成1,234 |
P或p | Percentage 百分符号格式 |
R或r | Round-trip 圆整(只用于浮点数)保证一个数字被转化成字符串以后可以再被转回成同样的数字 |
X或x | Hex 16进制格式 |
如果我们使用下面的表达方式,让我们看看会发生什么
publicclassFormatSpecApp
{
publicstaticvoidMain(string[]args)
{
inti=123456;
Console.WriteLine("{0:C}",i);//¥123,456.00
Console.WriteLine("{0:D}",i);//123456
Console.WriteLine("{0:E}",i);//1.234560E+005
Console.WriteLine("{0:F}",i);//123456.00
Console.WriteLine("{0:G}",i);//123456
Console.WriteLine("{0:N}",i);//123,456.00
Console.WriteLine("{0:P}",i);//12,345,600.00%
Console.WriteLine("{0:X}",i);//1E240
}
}
Console.WriteLine("{0:C5}",i);//¥123,456.00
Console.WriteLine("{0:D5}",i);//123456
Console.WriteLine("{0:E5}",i);//1.23456E+005
Console.WriteLine("{0:F5}",i);//123456.00000
Console.WriteLine("{0:G5}",i);//1.23456E5
Console.WriteLine("{0:N5}",i);//123,456.00000
Console.WriteLine("{0:P5}",i);//12,345,600.00000%
Console.WriteLine("{0:X5}",i);//1E240
doubled=1.2345678901234567890;
Console.WriteLine("Floating-Point:t{0:F16}",d); //1.2345678901234600
Console.WriteLine("Roundtrip:t{0:R16}",d); //1.2345678901234567
最大位数,定位符号,负号的外观以及其它数字符号的外观。就像下表所示
符号 | 名称 | 含义 |
0 | 0占位符 | 用0填充不足的位数 |
# | 数字占位符 | 用#代替实际的位数 |
. | 十进制小数点 | |
, | 千位分隔符 | 用逗号进行千位分割,比如把1000分割成1,000 |
% | 百分符号 | 显示一个百分标识 |
E+0
E-0 e+0 e-0 |
指数符号 | 用指数符号格式化输出 |
专一字符 | 用于传统格式的格式化序列,比如"n"(新行) | |
'ABC'
"ABC" |
常量字符串 | 显示单引号或者双引号里面的字符串 |
; | 区域分隔符 | 如果数字会被格式化成整数,负数,或者0,用;来进行分隔 |
,. | 缩放符号 | 数字除以1000 |
看下面的例子:
doublei=123456.42;
Console.WriteLine();
Console.WriteLine("{0:000000.00}",i);//123456.42
Console.WriteLine("{0:00.00000000e+0}",i);//12.34564200e+4
Console.WriteLine("{0:0,.}",i); //123
Console.WriteLine("{0:#0.000}",i); //123456.420
Console.WriteLine("{0:#0.000;(#0.000)}",i); //123456.420
Console.WriteLine("{0:#0.000;(#0.000);<zero>}",i);//123456.420
Console.WriteLine("{0:#%}",i); //12345642%
i=-123456.42;
Console.WriteLine();
Console.WriteLine("{0:000000.00}",i);//-123456.42
Console.WriteLine("{0:00.00000000e+0}",i);//-12.34564200e+4
Console.WriteLine("{0:0,.}",i); //-123
Console.WriteLine("{0:#0.000}",i); //-123456.420
Console.WriteLine("{0:#0.000;(#0.000)}",i); //(123456.420)
Console.WriteLine("{0:#0;(#0);<zero>}",i);//(123456)
Console.WriteLine("{0:#%}",i); //-12345642%
i=0;
Console.WriteLine();
Console.WriteLine("{0:0,.}",i); //0
Console.WriteLine("{0:#0}",i); //0
Console.WriteLine("{0:#0;(#0)}",i); //0
Console.WriteLine("{0:#0;(#0);<zero>}",i);//<zero>
Console.WriteLine("{0:#%}",i); //%
所有的基础类型都有ToString方法,它是从object类型中继承过来的。所有的数值类型都有Parse方法,它用字符串为参数,并且返回相等的数值。比如
publicclassNumParsingApp
{
publicstaticvoidMain(string[]args)
{
inti=int.Parse("12345");
Console.WriteLine("i={0}",i);
intj=Int32.Parse("12345");
Console.WriteLine("j={0}",j);
doubled=Double.Parse("1.2345E+6");
Console.WriteLine("d={0:F}",d);
strings=i.ToString();
Console.WriteLine("s={0}",s);
}
}
i=12345
j=12345
d=1234500.00
s=12345
stringt=" -1,234,567.890 ";
//doubleg=double.Parse(t); //和下面的代码干同样的事情
doubleg=double.Parse(t,
NumberStyles.AllowLeadingSign|
NumberStyles.AllowDecimalPoint|
NumberStyles.AllowThousands|
NumberStyles.AllowLeadingWhite|
NumberStyles.AllowTrailingWhite);
Console.WriteLine("g={0:F}",g);
g=-1234567.89
注意到,如果你要使用NumberStyles,就要添加对System.Globalization的引用,然后就可以使用不同NumberStyles的组合或者其中的任意一种。如果你想兼容货币符号,就需要使用重载的Parse方法,它们采用了NumberFormatInfo对象作为一个参数,然后你可以设置NumberFormatInfo的CurrencySymbol属性来调用Parse方法,比如:
stringu="¥ -1,234,567.890 ";
NumberFormatInfoni=newNumberFormatInfo();
ni.CurrencySymbol="¥";
doubleh=Double.Parse(u,NumberStyles.Any,ni);
Console.WriteLine("h={0:F}",h);
h=-1234567.89
intk=12345;
CultureInfous=newCultureInfo("en-US");
stringv=k.ToString("c",us);
Console.WriteLine(v);
$12,345.00
要注意到,我们使用了重载的ToString方法,它把第一个格式化字符串当成第一个参数,将一个CultureInfo对象(执行了IFormatProvider对象)作为第二个参数。这儿有第二个例子,对于丹麦人来说:
CultureInfodk=newCultureInfo("da-DK");
stringw=k.ToString("c",dk);
Console.WriteLine(w);
kr12.345,00
5 字符串和日期一个日期对象有个叫Ticks的属性。它存储了自从公元1年的1月1号上午12点开始的,以100纳秒为间隔的时间。比如,Ticks值等于31241376000000000L表示公元100年,星期五,1月1号,上午12点这一时间。Ticks总是以100纳秒为间隔递增。
DateTime的值以存储在DateTimeFormatInfo实例里面的标准或者自定义的方式来表示。为了修改一个日期显示的方式,DateTimeFormatInfo实例必须要是可写的,以便我们写入自定义的格式并且存入属性中
usingSystem.Globalization;
publicclassDatesApp
{
publicstaticvoidMain(string[]args)
{
DateTimedt=DateTime.Now;
Console.WriteLine(dt);
Console.WriteLine("date={0},time={1}n",
dt.Date,dt.TimeOfDay);
}
}
23/06/200117:55:10
date=23/06/200100:00:00,time=17:55:10.3839296下表列出了标准的格式字符串以及相关的DateTimeFormatInfo属性
D | ||
D | MM/dd/yyyy | ShortDatePattern(短日期模式) |
D | dddd,MMMM dd,yyyy | LongDatePattern(长日期模式) |
F | dddd,MMMM dd,yyyy HH:mm | Full date and time (long date and short time)(全日期和时间模式) |
F | dddd,MMMM dd,yyyy HH:mm:ss | FullDateTimePattern (long date and long time)(长日期和长时间) |
G | MM/dd/yyyy HH:mm | General (short date and short time)(通用模式,短日期和短时间) |
G | MM/dd/yyyy HH:mm:ss | General (short date and long time)(通用模式,短日期和长时间) |
M,M | MMMM dd | MonthDayPattern(月天模式) |
r,R | ddd,dd MMM yyyy,HH':'mm':'ss 'GMT' | RFC1123Pattern (RFC1123模式) |
S | yyyy-MM-dd HH:mm:ss | SortableDateTimePattern (conforms to ISO 8601) using local time(使用本地时间的可排序模式) |
T | HH:mm | ShortTimePattern (短时间模式) |
T | HH:mm:ss | LongTimePattern(长时间模式) |
U | yyyy-MM-dd HH:mm:ss | UniversalSortable-DateTimePattern (conforms to ISO 8601) using universal time(通用可排序模式) |
U | dddd,MMMM dd,yyyy,HH:mm:ss | UniversalSortable-DateTimePattern(通用可排序模式) |
y,Y | MMMM,yyyy | YearMonthPattern(年月模式) |
DateTimeFormatInfo.InvariantInfo属性得到了默认的只读的DateTimeFormatInfo实例,它与文化无关。你可以创建自定义的模式。要注意到的是InvariantInfo不一定和本地的格式一样。Invariant等于美国格式。另外,如果你向DateTime.Format方法传递的第二个参数是null,DateTimeFormatInfo将会是默认的CurrentInfo。比如
Console.WriteLine(dt.ToString("d",dtfi));
Console.WriteLine(dt.ToString("d",null));
Console.WriteLine();
06/23/2001
23/06/2001对比选择InvariantInfo和CurrentInfo的。
DateTimeFormatInfodtfi;
Console.Write("[I]nvariantor[C]urrentInfo?:");
if(Console.Read()=='I')
dtfi=DateTimeFormatInfo.InvariantInfo;
else
dtfi=DateTimeFormatInfo.CurrentInfo;
DateTimeFormatInfodtfi=DateTimeFormatInfo.InvariantInfo;
Console.WriteLine(dt.ToString("D",dtfi));
Console.WriteLine(dt.ToString("f",dtfi));
Console.WriteLine(dt.ToString("F",dtfi));
Console.WriteLine(dt.ToString("g",dtfi));
Console.WriteLine(dt.ToString("G",dtfi));
Console.WriteLine(dt.ToString("m",dtfi));
Console.WriteLine(dt.ToString("r",dtfi));
Console.WriteLine(dt.ToString("s",dtfi));
Console.WriteLine(dt.ToString("t",dtfi));
Console.WriteLine(dt.ToString("T",dtfi));
Console.WriteLine(dt.ToString("u",dtfi));
Console.WriteLine(dt.ToString("U",dtfi));
Console.WriteLine(dt.ToString("d",dtfi));
Console.WriteLine(dt.ToString("y",dtfi));
Console.WriteLine(dt.ToString("dd-MMM-yy",dtfi));
[I]nvariantor[C]urrentInfo?:I
01/03/2002
03/01/2002
Thursday,03January2002
Thursday,03January200212:55
Thursday,03January200212:55:03
01/03/200212:55
01/03/200212:55:03
January03
Thu,03Jan200212:55:03GMT
2002-01-03T12:55:03
12:55
12:55:03
2002-01-0312:55:03Z
Thursday,03January200212:55:03
01/03/2002
2002January
03-Jan-02
[I]nvariantor[C]urrentInfo?:C
03/01/2002
03/01/2002
03January2002
03January200212:55
03January200212:55:47
03/01/200212:55
03/01/200212:55:47
03January
Thu,03Jan200212:55:47GMT
2002-01-03T12:55:47
12:55
12:55:47
2002-01-0312:55:47Z
03January200212:55:47
03/01/2002
January2002
03-Jan-02