Một trong những điều vất vả nhất của các ngôn ngữ lập trình cấp thấp đó chính là định dạng kiểu chuỗi. Nhưng trong C#, mọi chuyện sẽ thật đơn giản!
Để So sánh Định dạng chuỗi trong C ta làm như sau:
char szOutput[256];
sprintf(szOutput, "At loop position %d.\n", i);
Lệnh sprintf thông qua 1 vùng đệm ra, 1 chuỗi định dạng và bất kỳ còn số nào của tham số để thay thế vào chuỗi định dạng đó. điều này hay gây ra lỗi tràn vùng đệm.
Tương đương với Lệnh sprintf trong C# là String.Format, sẽ lấy 1 chuỗi có định dạng và 1 tham số. Nó trả về 1 chuỗi và bởi vì bạn không truyền thông qua vùng đệm nên không sợ bị lỗi tràn vùng đệm như trong C. ta xem câu lệnh sau:
string outputString = String.Format("At loop position {0}.\n", i);
Vì vậy, tại sao lại không có các kiểu tham số định dạng mà có các tham số đặc tả những kiểu mà bạn cần định dạng nhỉ? Đối tượng CLR có những siêu dữ liệu (matadata) mà thể hiện tất cả những gì mà bạn cần và mỗi đối tượng đều có một phương thức ToString() chuẩn để trả về kiểu string của đối tượng đó.
Phương thức ToString có thể chấp nhận 1 tham số kiểu string mà tham số đó sẽ thông báo định dạng của đối tượng đó. Khi chúng ta dùng lệnh String.Format, chuỗi định dạng sẽ được truyền sau vị trí đó. Ví dụ: "{0:##}". các kí tự trong dấu ngoặc nhọn bắt đầu bằng {index của tham số [căn lề] : [Kiểu định dạng]}. Nếu Căn lề là số dương, thì chuỗi string sẽ được căn phải so với độ dài của chuỗi. Còn nếu là số âm thì sẽ được căn bên trái.
Các Kiểu Định Dạng
Quả thực, khi nói như vậy cũng rất là khó hiểu, nhưng khi thực hành, thì các bạn sẽ thấy đơn giản hơn rất nhiều. Có thể nói đó là lí do tại sao các sinh viên việt nam rất thông minh và học giỏi, nhưng khi bước vào thực tiễn công việc lại rất bỡ ngỡ.
Quay trở lại vấn đề, không có quá nhiều định dạng dành cho kiểu chuỗi. Đối với kiểu string, chỉ đơn giản là định dạng căn lề. Bạn hãy xem ví dụ sau nhé:
example | output |
---|---|
String.Format("--{0,10}--", "test"); | -- test-- |
String.Format("--{0,-10}--", "test"); | --test -- |
các kiểu định dạng số
Định dạng kiểu số là một loại độc lập. Ví dụ, định dạng một kí tự tiền tệ để hiển thị giá trị tiền của laptop sẽ trả về giá trị như sau: £9.99. Chúng ta hãy xem bảng giới thiệu bên dưới:
specifier | type | format | output (double 1.2345) | output (int -12345) |
---|---|---|---|---|
c | currency | {0:c} | £1.23 | -£12,345.00 |
d | decimal (whole number) | {0:d} | System.FormatException | -12345 |
e | exponent / scientific | {0:e} | 1.234500e+000 | -1.234500e+004 |
f | fixed point | {0:f} | 1.23 | -12345.00 |
g | general | {0:g} | 1.2345 | -12345 |
n | number | {0:n} | 1.23 | -12,345.00 |
r | round trippable | {0:r} | 1.23 | System.FormatException |
x | hexadecimal | {0:x4} | System.FormatException | ffffcfc7 |
Các bạn hãy để ý rằng chuỗi định dạng thường bắt đầu với các ký tự đầu của các kiểu mà bạn muốn chuyển sang.
Tùy biến cho định dạng kiểu số:
specifier | type | format | output (double 1234.56) |
---|---|---|---|
0 | zero placeholder | {0:00.000} | 1234.560 |
# | digit placeholder | {0:#.##} | 1234.56 |
. | decimal point placeholder | {0:0.0} | 1234.6 |
, | thousand separator | {0:0,0} | 1,235 |
% | percentage | {0:0%} | 123456% |
ta thấy, trong việc định dạng cho kí tự, có rất nhiều các kí tự ngăn cách và được chia thành các nhóm khác nhau: Kí tự 0 thay thế cho kí tự thừa bằng số 0, kí tự # thay thế cho các vị trí định dạng bằng các con số, dấu chấm (.) , dấu phẩy (,) và kí tự % ...
String.Format("{0:£#,##0.00;(£#,##0.00);Nothing}", value);
chuỗi lệnh trên nếu ta truyền vào một giá trị là 1234.56 thì giá trị trả về sẽ là "£1,240.00". và nếu các con số là 0 thì chuỗi kết quả nhận được sẽ là chuỗi "Nothing".
Định dạng ngày tháng:
Định dạng theo kiểu ngày phụ thuộc thông tinh Culture được truyền vào. Các ví dụ sau sẽ thể hiện rõ hơn các đặc tả về định dạng ngày tháng:
specifier | type | output (June 8, 1970 12:30:59) |
---|---|---|
d | Short Date | 08/06/1970 |
D | Long Date | 08 June 1970 |
t | Short Time | 12:30 |
T | Long Time | 12:30:59 |
f | Full date and time | 08 June 1970 12:30 |
F | Full date and time (long) | 08 June 1970 12:30:59 |
g | Default date and time | 08/06/1970 12:30 |
G | Default date and time (long) | 08/06/1970 12:30:59 |
M | Day / Month | 8 June |
r | RFC1123 date string | Mon, 08 Jun 1970 12:30:59 GMT |
s | Sortable date/time | 1970-06-08T12:30:59 |
u | Universal time, local timezone | 1970-06-08 12:30:59Z |
Y | Month / Year | June 1970 |
Bên trên là định dạng ngày tháng theo UK, còn nếu theo kiểu việt thường dùng thì ta dùng lệnh sau:
ví dụ định dạng ngày tháng cho một giá trị trong gridview hay datalist ta dùng lệnh : <%# Eval("value", "{0: dd/MM/yyyy}") %>
Định dạng ngày tháng tùy biến:
specifier | type | output (June 8, 1970 12:30:59) |
---|---|---|
dd | Day | 08 |
ddd | Short Day Name | Mon |
dddd | Full Day Name | Monday |
hh | 2 digit hour | 12 |
HH | 2 digit hour (24 hour) | 12 |
mm | 2 digit minute | 30 |
MM | Month | 06 |
MMM | Short Month name | Jun |
MMMM | Month name | June |
ss | seconds | 59 |
tt | AM/PM | PM |
yy | 2 digit year | 70 |
yyyy | 4 digit year | 1970 |
: | seperator, e.g. {0:hh:mm:ss} | 12:30:59 |
/ | seperator, e.g. {0:dd/MM/yyyy} | 08/06/1970 |
trên đây là một số các định dạng thông thường mà chúng ta hay dùng.
Thông Tin Culture
string.format cũng cung cấp 1 số hàm mà chấp nhận các tham số CultureInfo, như là IFormatProvider. Điều này rất quan trọng khi bạn cố gắng viết các đoạn mã linh động và mang tính chất hình thái. Ví dụ, tên của tháng sẽ thay đổi theo định dạng ngôn ngữ và văn hóa đang chạy trên máy của chúng ta. Thật là đơn giản khi chỉ cần dùng câu lệnh String.Format, và các hàm Overloaded khác. Nếu bạn không cần chỉ rõ 1 culture, bạn có thể dùng System.Globalization.CultureInfo.InvariantCulture, nó sẽ đặt định dạng của bạn theo kiểu English, khác với culture đang dùng hiện tại.
1 comments:
Bài viết bổ ích quá, Cám ơn anh đã chia sẻ cho mọi người, nếu được anh lên cập nhật cả các ví dụ nữa sẽ dễ hiểu hơn.
Đăng nhận xét