20.3 字符串格式化

先来看一段代码,如代码清单20-6所示。

代码清单20-6 字符串格式化


string s1="Tom";

string s2="Jack";

string s3=string.Format("{0}and{1}",s1,s2);

Console.WriteLine("{0}and{1}",s1,s2);


在这段代码中,无论是string.Format还是Console.WriteLine,共同点都是对字符串进行了格式化,出现在代码中的"{0}"和"{1}"都是占位符,它们终究会被值s1和s2所取代,其中占位符中的0和1都是索引,对应着真实值的索引位置,这是将占位符替换为值的依据。还要说一下,这两者都遵守同样的格式化规则。

回过头来,再来看看string.Format和Console.WriteLine方法。string.Format方法有5个重载:

❑Format(string format,params object[]args);

❑Format(string format,object arg0);

❑Format(IFormatProvider provider,string format,params object[]args);

❑Format(string format,object arg0,object arg1);

❑Format(string format,object arg0,object arg1,object arg2);

显然,这里使用的是第4个,第2、5个重载分别在值的数目为1个和3个的时候使用,如果值多于3个则只能使用第1或第3个重载版本。

Console.WriteLine的方法就多了,一共有19个重载版本,但可以进行格式化输出的重载版本只有5个:

❑WriteLine(string format,object arg0);

❑WriteLine(string format,params object[]arg);

❑WriteLine(string format,object arg0,object arg1);

❑WriteLine(string format,object arg0,object arg1,object arg2);

❑WriteLine(string format,object arg0,object arg1,object arg2,object arg3,__arglist);

可以结合前面介绍的Format重载来理解,这里就不再赘述。只不过,细心的读者可能会注意到第5个重载版本的最后一个参数:arglist,它是一个未公开的关键字,我们曾在第3章介绍关键字时提到过,这里简单看一下它的用法。使用arglist关键字可以方便地实现可变参数,示例如代码清单20-7所示:

代码清单20-7 未公开参数__arglist的示例


using System;

namespace ProgrammingCSharp4

{

class RegexSample

{

public static void Main()

{

Log(__arglist("success"));

Log(__arglist("success","ok"));

Log(__arglist("success","404",500));

Log(__arglist("success","404",500,new RegexSample()));

}

public static void Log(__arglist)

{

ArgIterator args=new ArgIterator(__arglist);

while(args.GetRemainingCount()>0)

{

Console.WriteLine("[{0}]{1}",DateTime.Now.ToLongTimeString(),

TypedReference.ToObject(args.GetNextArg()));

}

}

}

}


上述代码的运行结果如下:


[10:16:09]success

[10:16:09]success

[10:16:09]ok

[10:16:09]success

[10:16:09]404

[10:16:09]500

[10:16:09]success

[10:16:09]404

[10:16:09]500

[10:16:09]ProgrammingCSharp4.RegexSample

请按任意键继续……


简单看一下__arglist关键字的用法,书归正传,我们继续讨论字符格式化的语法。前文中提到了格式化字符串,就是Format以及WriteLine或者Write方法中的format参数,为什么"{0}"和"{1}"表示占位符而不是别的呢?接下来就阐述格式化字符串的语法问题。

格式字符串的语法是:


{index[,alignment][:formatString]}


其中各项的含义如表20-4所示。

20.3 字符串格式化 - 图1

需要说明的是,如果需要在格式化字符串中使用花括号,必须使用连续两个花括号的形式——"{{……}}"。

接下来我们介绍一下部分格式字符串。

格式化数值型数据可以使用“标准数字格式字符串”或者“自定义数字格式字符串”。先讲标准数字格式字符串,它的格式为“格式说明符+精度说明符”,其中格式说明符如表20-5所示,精度说明符可选,它的取值范围为0~99的整数。

20.3 字符串格式化 - 图2

接下来,使用一段代码来演示如何使用这些格式字符,如代码清单20-8所示。

代码清单20-8 使用数字格式字符串示例代码


using System;

namespace ProgrammingCSharp4

{

class RegexSample

{

public static void Main()

{

int integralVal=-12345;

double floatingVal=-1234.567d;

string msgCurrency=“(C)货币格式:……”;

string msgDecimal=“(D)十进制格式:……”;

string msgScientific=“(E)科学计数(指数)格式:……”;

string msgFixedPoint=“(F)固定点格式:……”;

string msgGeneral=“(G)常规(默认)格式:..”;

string msgNumber=“(N)数字格式:……”;

string msgPercent=“(P)百分比格式:……”;

string msgRoundTrip=“(R)往返格式:……”;

string msgHexadecimal=“(X)十六进制格式:……”;

string msgIntegralVal=“整数:”;

string msgFloatingVal=“小数:”;

Console.Clear();

Console.WriteLine("{0,-26}{1}",msgIntegralVal,integralVal);

Console.WriteLine("{0,-26}{1}",msgFloatingVal,floatingVal);

Console.WriteLine(msgDecimal+string.Format("{0:D}",integralVal));

Console.WriteLine(msgHexadecimal+string.Format("{0:X}",integralVal));

Console.WriteLine(msgRoundTrip+string.Format("{0:R}",floatingVal));

Console.WriteLine(msgCurrency+string.Format("{0:C}",floatingVal));

Console.WriteLine(msgScientific+string.Format("{0:E}",floatingVal));

Console.WriteLine(msgFixedPoint+string.Format("{0:F}",floatingVal));

Console.WriteLine(msgGeneral+string.Format("{0:G}",floatingVal));

Console.WriteLine(msgNumber+string.Format("{0:N1}",floatingVal));

Console.WriteLine(msgPercent+string.Format("{0:P}",floatingVal));

Console.WriteLine();

}

}

}


上述代码的运行结果如下:


整数:-12345

小数:-1234.567

(D)十进制格式:……-12345

(X)十六进制格式:……FFFFCFC7

(R)往返格式:……-1234.567

(C)货币格式:……¥-1,234.57

(E)科学计数(指数)格式:……-1.234567E+003

(F)固定点格式:……-1234.57

(G)常规(默认)格式:..-1234.567

(N)数字格式:……-1,234.6

(P)百分比格式:……-123,456.70%

请按任意键继续……


接下来,我们简单看一下如何使用“自定义数字格式字符串”。自定义数字格式字符串由一个或多个自定义数字格式说明符组成,用于定义格式化数值数据的方式。自定义数字格式说明符如表20-6所示。

20.3 字符串格式化 - 图3

接下来是个简单示例,如代码清单20-9所示。

代码清单20-9 使用自定义数字格式字符串的示例


using System;

namespace ProgrammingCSharp4

{

class RegexSample

{

public static void Main()

{

Double myDouble=1234567890;

int MyInt=42;

Console.WriteLine(String.Format("{0:(###)###-####}",myDouble));

Console.WriteLine(String.Format("{0:My Number=#}",MyInt));

}

}

}


上述代码的运行结果为:


(123)456-7890

My Number=42

请按任意键继续……