1. 程式人生 > >函數中{}輸出格式詳解(C#)

函數中{}輸出格式詳解(C#)

with content c-s sort 命名方式 發現 1-1 原始的 des

Console.WriteLine()函數中{}輸出格式詳解(C#)

Console.WriteLine()函數的格式一直沒怎麽註意。今天同事問起Console.WriteLine({0:D3},a)的意義,忽然發現不知道D代表什麽意義。以前以為{0,4}是指第一個變量輸出時占8位,今天查了一下,發現也並不完全正確。


其中格式項都采用如下形式:

{index[,alignment][:formatString]}

其中"index"指索引占位符,這個肯定都知道;

",alignment"按字面意思顯然是對齊方式,以","為標記;

":formatString"就是對輸出格式的限定,以":"為標記。

alignment:可選,是一個帶符號的整數,指示首選的格式化字段寬度。如果“對齊”值小於格式化字符串的長度,“對齊”會被忽略,並且使用格式化字符串的長度作為字段寬度。如果“對齊”為正數,字段的格式化數據為右對齊;如果“對齊”為負數,字段的格式化數據為左對齊。如果需要填充,則使用空白。如果指定“對齊”,就需要使用逗號。

formatString:由標準或自定義格式說明符組成.

下表是從網上得來:

字符

說明

示例

輸出

C 貨幣 string.Format("{0:C3}", 2) $2.000
D 十進制 string.Format("{0:D3}", 2) 002
E 科學計數法 1.20E+001 1.20E+001
G 常規 string.Format("{0:G}", 2) 2
N 用分號隔開的數字 string.Format("{0:N}", 250000) 250,000.00
X 十六進制 string.Format("{0:X000}", 12) C
string.Format("{0:000.000}", 12.2) 012.200



Specifier Type Format Output
(Passed
Double 1.42)
Output
(Passed
Int -12400)
c Currency {0:c} $1.42 -$12,400
d Decimal (Whole number) {0:d} System.
FormatException
-12400
e Scientific {0:e} 1.420000e+000 -1.240000e+004
f Fixed point {0:f} 1.42 -12400.00
g General {0:g} 1.42 -12400
n Number with commas for thousands {0:n} 1.42 -12,400
r Round trippable {0:r} 1.42 System.
FormatException
x Hexadecimal {0:x4} System.
FormatException
cf90

Specifier Type Example (Passed System.DateTime.Now)
d Short date 10/12/2002
D Long date December 10, 2002
t Short time 10:11 PM
T Long time 10:11:29 PM
f Full date & time December 10, 2002 10:11 PM
F Full date & time (long) December 10, 2002 10:11:29 PM
g Default date & time 10/12/2002 10:11 PM
G Default date & time (long) 10/12/2002 10:11:29 PM
M Month day pattern December 10
r RFC1123 date string Tue, 10 Dec 2002 22:11:29 GMT
s Sortable date string 2002-12-10T22:11:29
u Universal sortable, local time 2002-12-10 22:13:50Z
U Universal sortable, GMT December 11, 2002 3:13:50 AM
Y Year month pattern December, 2002

Specifier Type Example Example Output
dd Day {0:dd} 10
ddd Day name {0:ddd} Tue
dddd Full day name {0:dddd} Tuesday
f, ff, ... Second fractions {0:fff} 932
gg, ... Era {0:gg} A.D.
hh 2 digit hour {0:hh} 10
HH 2 digit hour, 24hr format {0:HH} 22
mm Minute 00-59 {0:mm} 38
MM Month 01-12 {0:MM} 12
MMM Month abbreviation {0:MMM} Dec
MMMM Full month name {0:MMMM} December
ss Seconds 00-59 {0:ss} 46
tt AM or PM {0:tt} PM
yy Year, 2 digits {0:yy} 02
yyyy Year {0:yyyy} 2002
zz Timezone offset, 2 digits {0:zz} -05
zzz Full timezone offset {0:zzz} -05:00
: Separator {0:hh:mm:ss} 10:43:20
/ Separator {0:dd/MM/yyyy} 10/12/2002

CSDN中例子:

[c-sharp] view plain copy
  1. string myFName = "Fred";
  2. string myLName = "Opals";
  3. int myInt = 100;
  4. string FormatFName = String.Format("First Name = |{0,10}|", myFName);
  5. string FormatLName = String.Format("Last Name = |{0,10}|", myLName);
  6. string FormatPrice = String.Format("Price = |{0,10:C}|", myInt);
  7. Console.WriteLine(FormatFName);
  8. Console.WriteLine(FormatLName);
  9. Console.WriteLine(FormatPrice);
  10. FormatFName = String.Format("First Name = |{0,-10}|", myFName);
  11. FormatLName = String.Format("Last Name = |{0,-10}|", myLName);//-10指左對齊,10個寬度,
  12. FormatPrice = String.Format("Price = |{0,-10:C}|", myInt);//C指以貨幣形式輸出
  13. Console.WriteLine(FormatFName);
  14. Console.WriteLine(FormatLName);
  15. Console.WriteLine(FormatPrice);
  16. //運行結果
  17. //First Name = | Fred|
  18. //Last Name = | Opals|
  19. //Price = | $100.00|
  20. //First Name = |Fred |
  21. //Last Name = |Opals |
  22. //Price = |$100.00 |

String 用法::

這種寫法用過沒:string.Format("{0,-10}", 8) www.cnblogs.com 2011-08-03 18:46 做 .net 開發也若幹年了,如此寫法(下面代碼中黃色高亮部分)確是我第一次見(更別提用了):
1 2 3 4 var s1 = string.Format("{0,-10}", 8); var s2 = string.Format("{0,10}", 8); var s3 = string.Format("{0,20:yyyy-MM-dd}", DateTime.Today); var s4 = string.Format("4G 內存便宜了{0,12:C2},我打算買{1,4}條", 145, 2)
大括號中,索引後 分號前,有一個逗號和一個整數(減號表示負數)。 會格式化成為什麽樣子呢?看下調試截圖吧: 技術分享 從上圖中能大致看出此端倪,沒錯: tring.Format("{0,-10}", 8) 等同於 string.Format("{0}", 8).PadRight(10); tring.Format("{0,10}", 8) 等同於 string.Format("{0}", 8).PadLeft(10)。 String.Format 方法 format 參數由零或多個文本序列與零或多個索引占位符混合組成,其中索引占位符稱為格式項,對應於與此方法的參數列表中的對象。 格式設置過程將每個格式項替換為相應對象值的字符串表示形式。 格式項的語法如下: {index[,length][:formatString]} 方括號中的元素是可選的。 下表描述每個元素。 有關復合格式設置功能(包括格式項的語法)的更多信息,請參見復合格式。
元素說明
索引 要設置格式的對象的參數列表中的位置(從零開始)。 如果由 index 指定的對象為 null,則格式項將被 String.Empty 替換。 由於該重載在其參數列表中只有單個對象,index 的值必須始終為 0。 如果 index 位置沒有參數,將引發 FormatException。
,length 參數的字符串表示形式中包含的最小字符數。 如果該值是正的,則參數右對齊;如果該值是負的,則參數左對齊。
:formatString 要設置格式的對象支持的標準或自定義格式字符串。 formatString 的可能值與該對象的 ToString(format) 方法支持的值相同。 如果沒有指定 formatString,並且要設置格式的對象實現了 IFormattable 接口,則將傳遞 null 作為用作 IFormattable.ToString 格式字符串的 format 參數的值。
元素 說明 索引 ,length 參數的字符串表示形式中包含的最小字符數。 如果該值是正的,則參數右對齊;如果該值是負的,則參數左對齊。 :formatString MSDN 原文鏈接:Format 方法 (String, Object) ,length 其實把 String.PadLeft 和 String.PadRight 的功能融合在的 String.Format 方法中,簡化了代碼的編寫。 如果沒有這種格式,代碼寫起來麻煩多了:
1 2 3 var s5 = string.Format("4G 內存便宜了{0},我打算買{1}條", 145.ToString("C2").PadLeft(12), 2.ToString().PadLeft(4))
看起來不直觀,復雜,如文首代碼中的 “我打算買{1,4}條”。 實際使用少,沒用過的看了很納悶。

前言

如果你熟悉Microsoft Foundation Classes(MFC)的CString,Windows Template Library(WTL)的CString或者Standard Template Library(STL)的字符串類,那麽你對String.Format方法肯定很熟悉。在C#中也經常使用這個方法來格式化字符串,比如下面這樣: int x = 16; decimal y = 3.57m; string h = String.Format( "item {0} sells at {1:C}", x, y ); Console.WriteLine(h) 在我的機器上,可以得到下面的輸出: item 16 sells at ¥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‘); string u = 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) 輸出如下: Hello 123 45.67 True Q 4 5 6 7 8 Hello 123 45.67 True Q 4 5 6 7 8 2 字符串格式 String.Format和WriteLine都遵守同樣的格式化規則。格式化的格式如下:"{ N [, M ][: formatString ]}", arg1, ... argN,在這個格式中: 1) N是從0開始的整數,表示要格式化的參數的個數 2) M是一個可選的整數,表示格式化後的參數所占的寬度,如果M是負數,那麽格式化後的值就是左對齊的,如果M是正數,那麽格式化後的值是右對齊的 3) formatString是另外一個可選的參數,表示格式代碼 argN表示要格式化的表達式,和N是對應的。 如果argN是空值,那麽就用一個空字符串來代替。如果沒有formatString,那麽就用參數N對應的ToString方法來格式化。下面的語句會產生同樣的輸出: ublic class TestConsoleApp { public static void Main(string[] args) { Console.WriteLine(123); Console.WriteLine("{0}", 123); Console.WriteLine("{0:D3}", 123); } } 輸出是: 123 123 123 也可以通過String.Format得到同樣的輸出。 tring s = string.Format("123"); string t = string.Format("{0}", 123); string u = 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 格式化標識符 標準的數學格式字符串用於返回通常使用的字符串。它們通常象X0這樣的格式。X是格式化標識符,0是精度標識符。格式標識符號共有9種,它們代表了大多數常用的數字格式。就像下表所示:
字母 含義
C或c Currency 貨幣格式
D或d Decimal 十進制格式(十進制整數,不要和.Net的Decimal數據類型混淆了)
E或e Exponent 指數格式
F或f Fixed point 固定精度格式
G或g General 常用格式
N或 用逗號分割千位的數字,比如1234將會被變成1,234
P或 Percentage 百分符號格式
R或r Round-trip 圓整(只用於浮點數)保證一個數字被轉化成字符串以後可以再被轉回成同樣的數字
X或x Hex 16進制格式
如果我們使用下面的表達方式,讓我們看看會發生什麽 ublic class FormatSpecApp { public static void Main(string[] args) { int i = 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 } } 精度控制標識控制了有效數字的個數或者十進制數小數的位數。 R(圓整)格式僅僅對浮點數有效。這個值首先會用通用格式來格式化。對於雙精度數有15位精度,對於單精度數有7位精度。如果這個值可以被正確地解析回原始的數字,就會用通用格式符來格式化。如果不能解析回去的話,那麽就會用17位精度來格式化雙精度數,用9位精度來格式化單精度數。盡管我們可以在圓整標識符後面添加有效數字的位數,但是它會被忽略掉。 double d = 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
看下面的例子: double 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.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); // % 4 數字字符串的解析 所有的基礎類型都有ToString方法,它是從object類型中繼承過來的。所有的數值類型都有Parse方法,它用字符串為參數,並且返回相等的數值。比如 ublic class NumParsingApp { public static void Main(string[] args) { int i = int.Parse("12345"); Console.WriteLine("i = {0}", i); int j = Int32.Parse("12345"); Console.WriteLine("j = {0}", j); double d = Double.Parse("1.2345E+6"); Console.WriteLine("d = {0:F}", d); string s = i.ToString(); Console.WriteLine("s = {0}", s); } } 輸出如下 i = 12345 j = 12345 d = 1234500.00 s = 12345 在缺省狀況下,某些非數字字符是可以存在的。比如開頭和結尾的空白。逗號和小數點,加號和減號,因此,下面的Parse語句是一樣的 tring t = " -1,234,567.890 "; //double g = double.Parse(t); // 和下面的代碼幹同樣的事情 double g = 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方法,比如: 上面的代碼有如下輸出 h = -1234567.89 除了NumberFormatInfo,還可以使用CultureInfo類。CultureInfo代表了某種特定的文化,包括文化的名字,書寫的方式,日歷的格式。對於某種特定文化的操作是非常普遍的情況,比如格式化日期和排序。文化的命名方式遵從RFC1766標準,使用<語言代碼2>-<國家/地區碼2>的方式,其中的<語言代碼2>是兩個小寫的字母,它們來自ISO639-1;<國家/地區碼2>是兩個大寫字母,它們來自ISO3166。比如,美國英語是“en-US"。英國英語是"en-GB"。特立尼達和多巴哥英語是"en-TT"。例如,我們可以創建一個美國英語的CultureInfo對象並且基於這種文化將數字轉換成字符串。 int k = 12345; CultureInfo us = new CultureInfo("en-US"); string v = k.ToString("c", us); Console.WriteLine(v) 輸出是: $12,345.00 要註意到,我們使用了重載的ToString方法,它把第一個格式化字符串當成第一個參數,將一個CultureInfo對象(執行了IFormatProvider對象)作為第二個參數。這兒有第二個例子,對於丹麥人來說: CultureInfo dk = new CultureInfo("da-DK"); string w = k.ToString("c", dk); Console.WriteLine(w) 輸出是: kr 12.345,00 5 字符串和日期 一個日期對象有個叫Ticks的屬性。它存儲了自從公元1年的1月1號上午12點開始的,以100納秒為間隔的時間。比如,Ticks值等於31241376000000000L表示公元100年,星期五,1月1號,上午12點這一時間。Ticks總是以100納秒為間隔遞增。 DateTime的值以存儲在DateTimeFormatInfo實例裏面的標準或者自定義的方式來表示。為了修改一個日期顯示的方式,DateTimeFormatInfo實例必須要是可寫的,以便我們寫入自定義的格式並且存入屬性中 using System.Globalization; public class DatesApp { public static void Main(string[] args) { DateTime dt = DateTime.Now; Console.WriteLine(dt); Console.WriteLine("date = {0}, time = {1}\n", dt.Date, dt.TimeOfDay); } } 代碼會產生下面的輸出 23/06/2001 17:55:10 date = 23/06/2001 00: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: FullDateTimePattern (long date and long time)(長日期和長時間)
G MM/dd/yyyy HH:mm General (short date and short time)(通用模式,短日期和短時間)
G MM/dd/yyyy HH:mm: 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: SortableDateTimePattern (conforms to ISO 8601) using local time(使用本地時間的可排序模式)
T HH:mm ShortTimePattern (短時間模式)
T HH:mm: LongTimePattern(長時間模式)
U yyyy-MM-dd HH:mm: UniversalSortable-DateTimePattern (conforms to ISO 8601) using universal time(通用可排序模式)
U dddd,MMMM dd,yyyy,HH:mm: 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的。 DateTimeFormatInfo dtfi; Console.Write("[I]nvariant or [C]urrent Info?: "); if (Console.Read() == ‘I‘) dtfi = DateTimeFormatInfo.InvariantInfo; else dtfi = DateTimeFormatInfo.CurrentInfo; DateTimeFormatInfo dtfi = 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]nvariant or [C]urrent Info?: I 01/03/2002 03/01/2002 Thursday, 03 January 2002 Thursday, 03 January 2002 12:55 Thursday, 03 January 2002 12:55:03 01/03/2002 12:55 01/03/2002 12:55:03 January 03 Thu, 03 Jan 2002 12:55:03 GMT 2002-01-03T12:55:03 12:55 12:55:03 2002-01-03 12:55:03Z Thursday, 03 January 2002 12:55:03 01/03/2002 2002 January 03-Jan-02 [I]nvariant or [C]urrent Info?: C 03/01/2002 03/01/2002 03 January 2002 03 January 2002 12:55 03 January 2002 12:55:47 03/01/2002 12:55 03/01/2002 12:55:47 03 January Thu, 03 Jan 2002 12:55:47 GMT 2002-01-03T12:55:47 12:55 12:55:47 2002-01-03 12:55:47Z 03 January 2002 12:55:47 03/01/2002 January 2002 03-Jan-02 /****************************************************************************************** *【Author】:flyingbread *【Date】:2007年1月18日 *【Notice】: *1、本文為原創技術文章,首發博客園個人站點( http://flyingbread.cnblogs.com/

函數中{}輸出格式詳解(C#)