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-5所示,精度说明符可选,它的取值范围为0~99的整数。
接下来,使用一段代码来演示如何使用这些格式字符,如代码清单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-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
请按任意键继续……