이 문서는 이 API에 대한 참조 설명서를 보충하는 추가 설명을 제공합니다.
중요합니다
String.Format 메서드를 호출하거나 복합 형식 문자열을 사용하는 대신, 언어에서 지원하는 경우 보간된 문자열 을 사용할 수 있습니다. 보간된 문자열은 보간된 식을 포함하는 문자열입니다. 보간된 각 식은 식의 값으로 확인되고 문자열이 할당될 때 결과 문자열에 포함됩니다. 자세한 내용은 문자열 보간(C# 참조) 및 보간된 문자열(Visual Basic 참조)을 참조하세요.
예시
Format 메서드를 호출하는 수많은 예제는 이 문서 전체에 산재되어 있습니다. 전체 예제 집합을 다운로드할 수 있으며, 여기에는 C#용 .NET Core 프로젝트가 포함되어 있습니다.
다음은 문서에 포함된 몇 가지 예입니다.
형식 문자열 만들기
문자열 삽입
서식 항목
동일한 인덱스를 가진 항목 서식 지정
형식이 지정된 출력 제어
제어 서식
컨트롤 간격
컨트롤 정렬
정수 자릿수를 제어하다
소수 구분 기호 뒤의 숫자 수를 제어합니다.
결과 문자열에 리터럴 중괄호를 포함
서식 문자열을 문화에 민감하게 만들기
서식 지정 작업 사용자 지정
사용자 지정 서식 지정 작업
인터셉트 제공자 및 로마 숫자 포맷터
String.Format 메서드 시작
개체, 변수 또는 식의 값을 다른 문자열에 삽입해야 하는 경우 String.Format 사용합니다. 예를 들어 Decimal 값의 값을 문자열에 삽입하여 사용자에게 단일 문자열로 표시할 수 있습니다.
Decimal pricePerOunce = 17.36m;
String s = String.Format("The current price is {0} per ounce.",
pricePerOunce);
Console.WriteLine(s);
// Result: The current price is 17.36 per ounce.
let pricePerOunce = 17.36m
String.Format("The current price is {0} per ounce.", pricePerOunce)
|> printfn "%s"
// Result: The current price is 17.36 per ounce.
Dim pricePerOunce As Decimal = 17.36D
Dim s As String = String.Format("The current price is {0} per ounce.",
pricePerOunce)
' Result: The current price is 17.36 per ounce.
또한 해당 값의 서식을 제어할 수 있습니다.
Decimal pricePerOunce = 17.36m;
String s = String.Format("The current price is {0:C2} per ounce.",
pricePerOunce);
Console.WriteLine(s);
// Result if current culture is en-US:
// The current price is $17.36 per ounce.
let pricePerOunce = 17.36m
String.Format("The current price is {0:C2} per ounce.", pricePerOunce)
|> printfn "%s"
// Result if current culture is en-US:
// The current price is $17.36 per ounce.
Dim pricePerOunce As Decimal = 17.36D
Dim s As String = String.Format("The current price is {0:C2} per ounce.",
pricePerOunce)
' Result if current culture is en-US:
' The current price is $17.36 per ounce.
서식 외에도 맞춤 및 간격을 제어할 수 있습니다.
문자열 삽입
String.Format 형식 문자열로 시작하고 문자열로 변환되고 서식 문자열의 지정된 위치에 삽입되는 하나 이상의 개체 또는 식으로 시작합니다. 다음은 그 예입니다.
decimal temp = 20.4m;
string s = String.Format("The temperature is {0}°C.", temp);
Console.WriteLine(s);
// Displays 'The temperature is 20.4°C.'
let temp = 20.4m
String.Format("The temperature is {0}°C.", temp)
|> printfn "%s"
// Displays 'The temperature is 20.4°C.'
Dim temp As Decimal = 20.4D
Dim s As String = String.Format("The temperature is {0}°C.", temp)
Console.WriteLine(s)
' Displays 'The temperature is 20.4°C.'
형식 문자열의 {0} 형식 항목입니다.
0 문자열 값이 해당 위치에 삽입되는 개체의 인덱스입니다. (인덱스는 0부터 시작합니다.) 삽입할 개체가 문자열이 아니면 결과 문자열에 삽입하기 전에 해당 ToString 메서드를 호출하여 1로 변환합니다.
다음은 개체 목록에서 두 개의 형식 항목과 두 개의 개체를 사용하는 또 다른 예입니다.
string s = String.Format("At {0}, the temperature is {1}°C.",
DateTime.Now, 20.4);
Console.WriteLine(s);
// Output similar to: 'At 4/10/2015 9:29:41 AM, the temperature is 20.4°C.'
String.Format("At {0}, the temperature is {1}°C.", DateTime.Now, 20.4)
|> printfn "%s"
// Output similar to: 'At 4/10/2015 9:29:41 AM, the temperature is 20.4°C.'
Dim s As String = String.Format("At {0}, the temperature is {1}°C.",
Date.Now, 20.4)
' Output similar to: 'At 4/10/2015 9:29:41 AM, the temperature is 20.4°C.'
모든 서식 항목의 인덱스가 개체 목록에 일치하는 개체를 갖는 한 원하는 만큼의 서식 항목과 개체를 개체 목록에 포함할 수 있습니다. 또한 호출하는 오버로드에 대해 걱정할 필요가 없습니다. 컴파일러가 적절한 오버로드를 선택해 줍니다.
서식 제어
서식 문자열이 있는 서식 항목의 인덱스로 개체의 서식을 지정하는 방법을 제어할 수 있습니다. 예를 들어 {0:d} 개체 목록의 첫 번째 개체에 "d" 서식 문자열을 적용합니다. 다음은 단일 개체와 두 개의 형식 항목이 있는 예제입니다.
string s = String.Format("It is now {0:d} at {0:t}", DateTime.Now);
Console.WriteLine(s);
// Output similar to: 'It is now 4/10/2015 at 10:04 AM'
String.Format("It is now {0:d} at {0:t}", DateTime.Now)
|> printfn "%s"
// Output similar to: 'It is now 4/10/2015 at 10:04 AM'
Dim s As String = String.Format("It is now {0:d} at {0:t}",
Date.Now)
' Output similar to: 'It is now 4/10/2015 at 10:04 AM'
다양한 유형은 모든 숫자 형식(표준 및 사용자 지정 형식 문자열), 모든 날짜 및 시간(표준 및 사용자 지정 형식 문자열), 시간 간격(표준 및 사용자 지정 형식 문자열), 모든 열거형 형식(열거형 형식), 그리고 GUID를 포함하여 형식 문자열을 지원합니다. 형식 문자열에 대한 지원을 사용자 고유의 형식에 추가할 수도 있습니다.
간격 제어
12자 문자열을 삽입하는 구 {0,12}문을 사용하여 결과 문자열에 삽입되는 문자열의 너비를 정의할 수 있습니다. 이 경우 첫 번째 개체의 문자열 표현은 12자 필드에서 오른쪽 맞춤됩니다. (첫 번째 개체의 문자열 표현 길이가 12자를 초과하는 경우 기본 설정 필드 너비는 무시되고 전체 문자열이 결과 문자열에 삽입됩니다.)
다음 예제에서는 문자열 "Year"와 일부 연도 문자열을 저장할 6자 필드와 문자열 "Population" 및 일부 모집단 데이터를 저장할 15자 필드를 정의합니다. 주의하세요, 문자가 필드에서 오른쪽으로 정렬되어 있습니다.
int[] years = { 2013, 2014, 2015 };
int[] population = { 1025632, 1105967, 1148203 };
var sb = new System.Text.StringBuilder();
sb.Append(String.Format("{0,6} {1,15}\n\n", "Year", "Population"));
for (int index = 0; index < years.Length; index++)
sb.Append(String.Format("{0,6} {1,15:N0}\n", years[index], population[index]));
Console.WriteLine(sb);
// Result:
// Year Population
//
// 2013 1,025,632
// 2014 1,105,967
// 2015 1,148,203
open System
open System.Text
let years = [| 2013; 2014; 2015 |]
let population = [| 1025632; 1105967; 1148203 |]
let sb = StringBuilder()
sb.Append(String.Format("{0,6} {1,15}\n\n", "Year", "Population")) |> ignore
for i = 0 to years.Length - 1 do
sb.Append(String.Format("{0,6} {1,15:N0}\n", years[i], population[i])) |> ignore
printfn $"{sb}"
// Result:
// Year Population
//
// 2013 1,025,632
// 2014 1,105,967
// 2015 1,148,203
Dim years() As Integer = {2013, 2014, 2015}
Dim population() As Integer = {1025632, 1105967, 1148203}
Dim sb As New StringBuilder()
sb.Append(String.Format("{0,6} {1,15}{2}{2}",
"Year", "Population", vbCrLf))
For index As Integer = 0 To years.Length - 1
sb.AppendFormat("{0,6} {1,15:N0}{2}",
years(index), population(index), vbCrLf)
Next
' Result:
' Year Population
'
' 2013 1,025,632
' 2014 1,105,967
' 2015 1,148,203
컨트롤 정렬
기본적으로 필드 너비를 지정하는 경우 문자열은 해당 필드 내에서 오른쪽 맞춤됩니다. 필드의 문자열을 왼쪽에 맞추려면 필드 너비 앞에 음수 기호(예: {0,-12})를 추가하여 12자 왼쪽 맞춤 필드를 정의합니다.
다음 예제는 레이블과 데이터를 모두 왼쪽으로 정렬한다는 점을 제외하고 이전 예제와 비슷합니다.
int[] years = { 2013, 2014, 2015 };
int[] population = { 1025632, 1105967, 1148203 };
String s = String.Format("{0,-10} {1,-10}\n\n", "Year", "Population");
for (int index = 0; index < years.Length; index++)
s += String.Format("{0,-10} {1,-10:N0}\n",
years[index], population[index]);
Console.WriteLine($"\n{s}");
// Result:
// Year Population
//
// 2013 1,025,632
// 2014 1,105,967
// 2015 1,148,203
let years = [| 2013; 2014; 2015 |]
let population = [| 1025632; 1105967; 1148203 |]
let mutable s = String.Format("{0,-10} {1,-10}\n\n", "Year", "Population")
for i = 0 to years.Length - 1 do
s <- s + String.Format("{0,-10} {1,-10:N0}\n", years[i], population[i])
printfn $"\n{s}"
// Result:
// Year Population
//
// 2013 1,025,632
// 2014 1,105,967
// 2015 1,148,203
Dim years() As Integer = {2013, 2014, 2015}
Dim population() As Integer = {1025632, 1105967, 1148203}
Dim s As String = String.Format("{0,-10} {1,-10}{2}{2}",
"Year", "Population", vbCrLf)
For index As Integer = 0 To years.Length - 1
s += String.Format("{0,-10} {1,-10:N0}{2}",
years(index), population(index), vbCrLf)
Next
' Result:
' Year Population
'
' 2013 1,025,632
' 2014 1,105,967
' 2015 1,148,203
String.Format 복합 서식 기능을 사용합니다. 자세한 내용은 복합 서식 지정을 참조하세요.
어떤 메서드를 호출합니까?
| 목표 | 호출할 메서드 |
|---|---|
| 현재 문화권의 규칙을 사용하여 하나 이상의 개체 서식을 지정합니다. |
provider 매개 변수를 포함하는 오버로드를 제외하고 나머지 Format 오버로드는 하나 이상의 개체 매개 변수 뒤에 String 매개 변수를 포함합니다. 이 때문에 호출하려는 Format 오버로드를 확인할 필요가 없습니다. 언어 컴파일러는 인수 목록에 따라 provider 매개 변수가 없는 오버로드 중에서 적절한 오버로드를 선택합니다. 예를 들어 인수 목록에 5개의 인수가 있는 경우 컴파일러는 Format(String, Object[]) 메서드를 호출합니다. |
| 특정 문화권의 규칙을 사용하여 하나 이상의 개체 서식을 지정합니다. |
Format 매개 변수로 시작하는 각 provider 오버로드 뒤에는 String 매개 변수와 하나 이상의 개체 매개 변수가 잇습니다. 이 때문에 호출하려는 특정 Format 오버로드를 확인할 필요가 없습니다. 언어 컴파일러는 인수 목록에 따라 provider 매개 변수가 있는 오버로드 중에서 적절한 오버로드를 선택합니다. 예를 들어 인수 목록에 5개의 인수가 있는 경우 컴파일러는 Format(IFormatProvider, String, Object[]) 메서드를 호출합니다. |
| ICustomFormatter 구현 또는 IFormattable 구현을 사용하여 사용자 지정 서식 지정 작업을 수행합니다. |
provider 매개 변수가 있는 4개의 오버로드 중 어느 것이든지. 컴파일러는 인수 목록에 따라 provider 매개 변수가 있는 오버로드 중에서 적절한 오버로드를 선택합니다. |
Format 메서드를 간략하게 설명합니다.
Format 메서드의 각 오버로드는 복합 서식 지정 기능를 사용하여 복합 형식 문자열에 0부터 시작하는 인덱싱된 자리 표시자인 형식 항목를 포함합니다. 런타임 시 각 형식 항목은 매개 변수 목록에서 해당 인수의 문자열 표현으로 바뀝니다. 인수 값이 null경우 서식 항목이 String.Empty바뀝다. 예를 들어 Format(String, Object, Object, Object) 메서드에 대한 다음 호출에는 {0}, {1}및 {2}세 개의 형식 항목이 있는 형식 문자열과 세 개의 항목이 있는 인수 목록이 포함됩니다.
DateTime dat = new DateTime(2012, 1, 17, 9, 30, 0);
string city = "Chicago";
int temp = -16;
string output = String.Format("At {0} in {1}, the temperature was {2} degrees.",
dat, city, temp);
Console.WriteLine(output);
// The example displays output like the following:
// At 1/17/2012 9:30:00 AM in Chicago, the temperature was -16 degrees.
open System
let dat = DateTime(2012, 1, 17, 9, 30, 0)
let city = "Chicago"
let temp = -16
String.Format("At {0} in {1}, the temperature was {2} degrees.", dat, city, temp)
|> printfn "%s"
// The example displays output like the following:
// At 1/17/2012 9:30:00 AM in Chicago, the temperature was -16 degrees.
Dim dat As Date = #1/17/2012 9:30AM#
Dim city As String = "Chicago"
Dim temp As Integer = -16
Dim output As String = String.Format("At {0} in {1}, the temperature was {2} degrees.",
dat, city, temp)
Console.WriteLine(output)
' The example displays the following output:
' At 1/17/2012 9:30:00 AM in Chicago, the temperature was -16 degrees.
서식 항목
형식 항목에는 다음 구문이 있습니다.
{index[,width][:formatString]}
대괄호는 선택적 요소를 나타냅니다. 여는 중괄호와 닫는 중괄호가 필요합니다. 서식 문자열에 리터럴 여는 중괄호 또는 닫는 중괄호를 포함하려면 이스케이프 중괄호 섹션을 복합 서식 문서에서 참조하세요.
예를 들어 통화 값의 서식을 지정하는 서식 항목은 다음과 같이 표시될 수 있습니다.
var value = String.Format("{0,-10:C}", 126347.89m);
Console.WriteLine(value);
open System
String.Format("{0,-10:C}", 126347.89m)
|> printfn "%s"
String.Format("{0,-10:C}", 126347.89D)
형식 항목에는 다음과 같은 요소가 있습니다.
index
문자열 표현을 문자열의 이 위치에 포함할 인수의 인덱스(0부터 시작)입니다. 이 인수가 null경우 빈 문자열이 문자열의 이 위치에 포함됩니다.
width
선택 사항. 인수가 삽입되는 필드의 총 길이와 인수가 오른쪽 맞춤(양수) 또는 왼쪽 맞춤(음수 정수)인지 여부를 나타내는 부호 있는 정수입니다. 생략 width하면 선행 또는 후행 공백이 없는 필드에 해당 인수의 문자열 표현이 삽입됩니다.
값 width 이 삽입 width 할 인수의 길이보다 작으면 무시되고 인수의 문자열 표현 길이가 필드 너비로 사용됩니다.
formatString
선택 사항. 해당 인수의 결과 문자열 형식을 지정하는 문자열입니다. 생략 formatString하면 해당 인수의 매개 변수 없는 ToString 메서드가 호출되어 문자열 표현이 생성됩니다. 지정 formatString하는 경우 형식 항목에서 참조하는 인수가 인터페이스를 IFormattable 구현해야 합니다. 형식 문자열을 지원하는 형식은 다음과 같습니다.
모든 정수 및 부동 소수점 타입. (표준 숫자 서식 문자열 및 사용자 지정 숫자 서식 문자열 참조하세요.)
DateTime 및 DateTimeOffset. (표준 날짜 및 시간 형식 문자열 참조하고 사용자 지정 날짜 및 시간 서식 문자열 .)
모든 열거형 (열거형 형식 문자열참조하세요.)
TimeSpan 값입니다. 표준 TimeSpan 형식 문자열 및 사용자 지정 TimeSpan 형식 문자열참조하세요.
GUID. (Guid.ToString(String) 메서드를 참조하세요.)
그러나 모든 사용자 지정 형식은 기존 형식의 IFormattable 구현을 구현 IFormattable 하거나 확장할 수 있습니다.
다음 예제에서는 width 및 formatString 인수를 사용하여 형식이 지정된 출력을 생성합니다.
// Create array of 5-tuples with population data for three U.S. cities, 1940-1950.
Tuple<string, DateTime, int, DateTime, int>[] cities =
{ Tuple.Create("Los Angeles", new DateTime(1940, 1, 1), 1504277,
new DateTime(1950, 1, 1), 1970358),
Tuple.Create("New York", new DateTime(1940, 1, 1), 7454995,
new DateTime(1950, 1, 1), 7891957),
Tuple.Create("Chicago", new DateTime(1940, 1, 1), 3396808,
new DateTime(1950, 1, 1), 3620962),
Tuple.Create("Detroit", new DateTime(1940, 1, 1), 1623452,
new DateTime(1950, 1, 1), 1849568) };
// Display header
var header = String.Format("{0,-12}{1,8}{2,12}{1,8}{2,12}{3,14}\n",
"City", "Year", "Population", "Change (%)");
Console.WriteLine(header);
foreach (var city in cities) {
var output = String.Format("{0,-12}{1,8:yyyy}{2,12:N0}{3,8:yyyy}{4,12:N0}{5,14:P1}",
city.Item1, city.Item2, city.Item3, city.Item4, city.Item5,
(city.Item5 - city.Item3)/ (double)city.Item3);
Console.WriteLine(output);
}
// The example displays the following output:
// City Year Population Year Population Change (%)
//
// Los Angeles 1940 1,504,277 1950 1,970,358 31.0 %
// New York 1940 7,454,995 1950 7,891,957 5.9 %
// Chicago 1940 3,396,808 1950 3,620,962 6.6 %
// Detroit 1940 1,623,452 1950 1,849,568 13.9 %
// Create a list of 5-tuples with population data for three U.S. cities, 1940-1950.
let cities =
[ "Los Angeles", DateTime(1940, 1, 1), 1504277, DateTime(1950, 1, 1), 1970358
"New York", DateTime(1940, 1, 1), 7454995, DateTime(1950, 1, 1), 7891957
"Chicago", DateTime(1940, 1, 1), 3396808, DateTime(1950, 1, 1), 3620962
"Detroit", DateTime(1940, 1, 1), 1623452, DateTime(1950, 1, 1), 1849568 ]
// Display header
String.Format("{0,-12}{1,8}{2,12}{1,8}{2,12}{3,14}\n", "City", "Year", "Population", "Change (%)")
|> printfn "%s"
for name, year1, pop1, year2, pop2 in cities do
String.Format("{0,-12}{1,8:yyyy}{2,12:N0}{3,8:yyyy}{4,12:N0}{5,14:P1}",
name, year1, pop1, year2, pop2,
double (pop2 - pop1) / double pop1)
|> printfn "%s"
// The example displays the following output:
// City Year Population Year Population Change (%)
//
// Los Angeles 1940 1,504,277 1950 1,970,358 31.0 %
// New York 1940 7,454,995 1950 7,891,957 5.9 %
// Chicago 1940 3,396,808 1950 3,620,962 6.6 %
// Detroit 1940 1,623,452 1950 1,849,568 13.9 %
Module Example3
Public Sub Main()
' Create array of 5-tuples with population data for three U.S. cities, 1940-1950.
Dim cities() =
{Tuple.Create("Los Angeles", #1/1/1940#, 1504277, #1/1/1950#, 1970358),
Tuple.Create("New York", #1/1/1940#, 7454995, #1/1/1950#, 7891957),
Tuple.Create("Chicago", #1/1/1940#, 3396808, #1/1/1950#, 3620962),
Tuple.Create("Detroit", #1/1/1940#, 1623452, #1/1/1950#, 1849568)}
' Display header
Dim header As String = String.Format("{0,-12}{1,8}{2,12}{1,8}{2,12}{3,14}",
"City", "Year", "Population", "Change (%)")
Console.WriteLine(header)
Console.WriteLine()
For Each city In cities
Dim output = String.Format("{0,-12}{1,8:yyyy}{2,12:N0}{3,8:yyyy}{4,12:N0}{5,14:P1}",
city.Item1, city.Item2, city.Item3, city.Item4, city.Item5,
(city.Item5 - city.Item3) / city.Item3)
Console.WriteLine(output)
Next
End Sub
End Module
' The example displays the following output:
' City Year Population Year Population Change (%)
'
' Los Angeles 1940 1,504,277 1950 1,970,358 31.0 %
' New York 1940 7,454,995 1950 7,891,957 5.9 %
' Chicago 1940 3,396,808 1950 3,620,962 6.6 %
' Detroit 1940 1,623,452 1950 1,849,568 13.9 %
인수 형식 지정 방법
형식 항목은 문자열의 시작 부분에서 순차적으로 처리됩니다. 각 형식 항목에는 메서드의 인수 목록에 있는 개체에 해당하는 인덱스가 있습니다. Format 메서드는 인수를 검색하고 다음과 같이 문자열 표현을 파생합니다.
인수가
null경우 메서드는 결과 문자열에 String.Empty 삽입합니다. null 인수에 대해 NullReferenceException를 처리할 필요가 없습니다.Format(IFormatProvider, String, Object[]) 오버로드를 호출하고
provider개체의 IFormatProvider.GetFormat 구현이 null이 아닌 ICustomFormatter 구현을 반환하면 인수가 해당 ICustomFormatter.Format(String, Object, IFormatProvider) 메서드로 전달됩니다. 형식 항목에 인수가formatString포함된 경우 메서드에 첫 번째 인수로 전달됩니다. ICustomFormatter 구현을 사용할 수 있고 null이 아닌 문자열을 생성하는 경우 해당 문자열은 인수의 문자열 표현으로 반환됩니다. 그렇지 않으면 다음 단계가 실행됩니다.인수가 IFormattable 인터페이스를 구현하는 경우 해당 IFormattable.ToString 구현이 호출됩니다.
기본 클래스 구현에서 재정의하거나 상속하는 인수의 매개 변수 없는
ToString메서드가 호출됩니다.
ICustomFormatter.Format 메서드에 대한 호출을 가로채고 Format 메서드가 복합 형식 문자열의 각 서식 항목에 대한 서식 지정 메서드에 전달하는 정보를 확인할 수 있는 예제는 예제: 절편 공급자 및 로마 숫자 포맷터참조하세요.
자세한 내용은 처리 순서참조하세요.
인덱스가 같은 항목 서식 지정
인덱스 항목의 인덱스가 인수 목록의 인수 수보다 크거나 같은 경우 Format 메서드는 FormatException 예외를 throw합니다. 그러나 format 여러 서식 항목의 인덱스가 같으면 인수보다 더 많은 형식 항목을 포함할 수 있습니다. 다음 예제의 Format(String, Object) 메서드 호출에서 인수 목록에는 단일 인수가 있지만 형식 문자열에는 두 개의 형식 항목이 포함됩니다. 하나는 숫자의 10진수를 표시하고 다른 하나는 16진수 값을 표시합니다.
short[] values= { Int16.MinValue, -27, 0, 1042, Int16.MaxValue };
Console.WriteLine("{0,10} {1,10}\n", "Decimal", "Hex");
foreach (short value in values)
{
string formatString = String.Format("{0,10:G}: {0,10:X}", value);
Console.WriteLine(formatString);
}
// The example displays the following output:
// Decimal Hex
//
// -32768: 8000
// -27: FFE5
// 0: 0
// 1042: 412
// 32767: 7FFF
open System
let values= [| Int16.MinValue; -27s; 0s; 1042s; Int16.MaxValue |]
printfn "%10s %10s\n" "Decimal" "Hex"
for value in values do
String.Format("{0,10:G}: {0,10:X}", value)
|> printfn "%s"
// The example displays the following output:
// Decimal Hex
//
// -32768: 8000
// -27: FFE5
// 0: 0
// 1042: 412
// 32767: 7FFF
Module Example1
Public Sub Main()
Dim values() As Short = {Int16.MinValue, -27, 0, 1042, Int16.MaxValue}
Console.WriteLine("{0,10} {1,10}", "Decimal", "Hex")
Console.WriteLine()
For Each value As Short In values
Dim formatString As String = String.Format("{0,10:G}: {0,10:X}", value)
Console.WriteLine(formatString)
Next
End Sub
End Module
' The example displays the following output:
' Decimal Hex
'
' -32768: 8000
' -27: FFE5
' 0: 0
' 1042: 412
' 32767: 7FFF
서식과 문화
일반적으로 인수 목록의 개체는 CultureInfo.CurrentCulture 속성에서 반환되는 현재 문화권의 규칙을 사용하여 문자열 표현으로 변환됩니다.
Format 매개 변수를 포함하는 provider 오버로드 중 하나를 호출하여 이 동작을 제어할 수 있습니다.
provider 매개 변수는 서식 지정 프로세스를 조정하는 데 사용되는 사용자 지정 및 문화권별 서식 정보를 제공하는 IFormatProvider 구현입니다.
IFormatProvider 인터페이스에는 서식 정보를 제공하는 개체를 반환하는 단일 멤버인 GetFormat있습니다. .NET에는 문화권별 서식을 제공하는 세 가지 IFormatProvider 구현이 있습니다.
- CultureInfo; 해당 GetFormat 메서드는 숫자 값의 서식을 지정하기 위한 문화권별 NumberFormatInfo 개체와 날짜 및 시간 값의 서식을 지정하기 위한 문화권별 DateTimeFormatInfo 개체를 반환합니다.
- DateTimeFormatInfo- 날짜 및 시간 값의 문화권별 서식 지정에 사용됩니다. 해당 GetFormat 메서드는 자신을 반환합니다.
- NumberFormatInfo- 숫자 값의 문화권별 서식 지정에 사용됩니다. 해당 GetFormat(Type) 메서드는 자신을 반환합니다.
사용자 지정 서식 지정 작업
Format 형식의 provider 매개 변수가 있는 IFormatProvider 메서드의 오버로드를 호출하여 사용자 지정 서식 지정 작업을 수행할 수도 있습니다. 예를 들어 정수를 ID 번호 또는 전화 번호로 서식을 지정할 수 있습니다. 사용자 지정 서식을 수행하려면 provider 인수가 IFormatProvider 인터페이스와 ICustomFormatter 인터페이스를 모두 구현해야 합니다.
Format 메서드가 ICustomFormatter 구현을 provider 인수로 전달하면 Format 메서드는 IFormatProvider.GetFormat 구현을 호출하고 ICustomFormatter형식의 개체를 요청합니다. 그런 다음 반환된 ICustomFormatter 개체의 Format 메서드를 호출하여 전달된 복합 문자열의 각 서식 항목에 서식을 지정합니다.
사용자 지정 서식 지정 솔루션을 제공하는 방법에 대한 자세한 내용은 방법: 사용자 지정 숫자 형식 공급자 정의 및 사용 및 ICustomFormatter참조하세요. 정수를 서식이 지정된 사용자 지정 숫자로 변환하는 예제는 예제: 사용자 지정 서식 지정 작업참조하세요. 부호 없는 바이트를 로마 숫자로 변환하는 예제는 예제: 절편 공급자 및 로마 숫자 포맷터참조하세요.
예: 사용자 지정 서식 지정 작업
이 예제에서는 x-xxxxx-xx 형식의 정수 값 형식을 고객 계정 번호로 지정하는 형식 공급자를 정의합니다.
using System;
public class TestFormatter
{
public static void Main()
{
int acctNumber = 79203159;
Console.WriteLine(String.Format(new CustomerFormatter(), "{0}", acctNumber));
Console.WriteLine(String.Format(new CustomerFormatter(), "{0:G}", acctNumber));
Console.WriteLine(String.Format(new CustomerFormatter(), "{0:S}", acctNumber));
Console.WriteLine(String.Format(new CustomerFormatter(), "{0:P}", acctNumber));
try {
Console.WriteLine(String.Format(new CustomerFormatter(), "{0:X}", acctNumber));
}
catch (FormatException e) {
Console.WriteLine(e.Message);
}
}
}
public class CustomerFormatter : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
return this;
else
return null;
}
public string Format(string format,
object arg,
IFormatProvider formatProvider)
{
if (! this.Equals(formatProvider))
{
return null;
}
else
{
if (String.IsNullOrEmpty(format))
format = "G";
string customerString = arg.ToString();
if (customerString.Length < 8)
customerString = customerString.PadLeft(8, '0');
format = format.ToUpper();
switch (format)
{
case "G":
return customerString.Substring(0, 1) + "-" +
customerString.Substring(1, 5) + "-" +
customerString.Substring(6);
case "S":
return customerString.Substring(0, 1) + "/" +
customerString.Substring(1, 5) + "/" +
customerString.Substring(6);
case "P":
return customerString.Substring(0, 1) + "." +
customerString.Substring(1, 5) + "." +
customerString.Substring(6);
default:
throw new FormatException(
String.Format("The '{0}' format specifier is not supported.", format));
}
}
}
}
// The example displays the following output:
// 7-92031-59
// 7-92031-59
// 7/92031/59
// 7.92031.59
// The 'X' format specifier is not supported.
open System
type CustomerFormatter() =
interface IFormatProvider with
member this.GetFormat(formatType) =
if formatType = typeof<ICustomFormatter> then
this
else
null
interface ICustomFormatter with
member this.Format(format, arg, formatProvider: IFormatProvider) =
if this.Equals formatProvider |> not then
null
else
let format =
if String.IsNullOrEmpty format then "G"
else format.ToUpper()
let customerString =
let s = string arg
if s.Length < 8 then
s.PadLeft(8, '0')
else s
match format with
| "G" ->
customerString.Substring(0, 1) + "-" +
customerString.Substring(1, 5) + "-" +
customerString.Substring 6
| "S" ->
customerString.Substring(0, 1) + "/" +
customerString.Substring(1, 5) + "/" +
customerString.Substring 6
| "P" ->
customerString.Substring(0, 1) + "." +
customerString.Substring(1, 5) + "." +
customerString.Substring 6
| _ ->
raise (FormatException $"The '{format}' format specifier is not supported.")
let acctNumber = 79203159
String.Format(CustomerFormatter(), "{0}", acctNumber)
|> printfn "%s"
String.Format(CustomerFormatter(), "{0:G}", acctNumber)
|> printfn "%s"
String.Format(CustomerFormatter(), "{0:S}", acctNumber)
|> printfn "%s"
String.Format(CustomerFormatter(), "{0:P}", acctNumber)
|> printfn "%s"
try
String.Format(CustomerFormatter(), "{0:X}", acctNumber)
|> printfn "%s"
with :? FormatException as e ->
printfn $"{e.Message}"
// The example displays the following output:
// 7-92031-59
// 7-92031-59
// 7/92031/59
// 7.92031.59
// The 'X' format specifier is not supported.
Module TestFormatter
Public Sub Main()
Dim acctNumber As Integer = 79203159
Console.WriteLine(String.Format(New CustomerFormatter, "{0}", acctNumber))
Console.WriteLine(String.Format(New CustomerFormatter, "{0:G}", acctNumber))
Console.WriteLine(String.Format(New CustomerFormatter, "{0:S}", acctNumber))
Console.WriteLine(String.Format(New CustomerFormatter, "{0:P}", acctNumber))
Try
Console.WriteLine(String.Format(New CustomerFormatter, "{0:X}", acctNumber))
Catch e As FormatException
Console.WriteLine(e.Message)
End Try
End Sub
End Module
Public Class CustomerFormatter : Implements IFormatProvider, ICustomFormatter
Public Function GetFormat(type As Type) As Object _
Implements IFormatProvider.GetFormat
If type Is GetType(ICustomFormatter) Then
Return Me
Else
Return Nothing
End If
End Function
Public Function Format(fmt As String, _
arg As Object, _
formatProvider As IFormatProvider) As String _
Implements ICustomFormatter.Format
If Not Me.Equals(formatProvider) Then
Return Nothing
Else
If String.IsNullOrEmpty(fmt) Then fmt = "G"
Dim customerString As String = arg.ToString()
if customerString.Length < 8 Then _
customerString = customerString.PadLeft(8, "0"c)
Select Case fmt
Case "G"
Return customerString.Substring(0, 1) & "-" & _
customerString.Substring(1, 5) & "-" & _
customerString.Substring(6)
Case "S"
Return customerString.Substring(0, 1) & "/" & _
customerString.Substring(1, 5) & "/" & _
customerString.Substring(6)
Case "P"
Return customerString.Substring(0, 1) & "." & _
customerString.Substring(1, 5) & "." & _
customerString.Substring(6)
Case Else
Throw New FormatException( _
String.Format("The '{0}' format specifier is not supported.", fmt))
End Select
End If
End Function
End Class
' The example displays the following output:
' 7-92031-59
' 7-92031-59
' 7/92031/59
' 7.92031.59
' The 'X' format specifier is not supported.
예: 인터셉트 공급자 및 로마 숫자 포맷터
이 예제에서는 두 가지 작업을 수행하는 ICustomFormatter 및 IFormatProvider 인터페이스를 구현하는 사용자 지정 형식 공급자를 정의합니다.
- ICustomFormatter.Format 구현에 전달된 매개 변수를 표시합니다. 이렇게 하면 Format(IFormatProvider, String, Object[]) 메서드가 서식을 지정하려는 각 개체에 대한 사용자 지정 서식 구현으로 전달되는 매개 변수를 확인할 수 있습니다. 이 기능은 애플리케이션을 디버깅할 때 유용할 수 있습니다.
- 서식을 지정할 개체가 "R" 표준 서식 문자열을 사용하여 서식을 지정할 부호 없는 바이트 값인 경우 사용자 지정 포맷터는 숫자 값의 서식을 로마 숫자로 지정합니다.
using System;
using System.Globalization;
public class InterceptProvider : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
return this;
else
return null;
}
public string Format(String format, Object obj, IFormatProvider provider)
{
// Display information about method call.
string formatString = format ?? "<null>";
Console.WriteLine("Provider: {0}, Object: {1}, Format String: {2}",
provider.GetType().Name, obj ?? "<null>", formatString);
if (obj == null) return String.Empty;
// If this is a byte and the "R" format string, format it with Roman numerals.
if (obj is Byte && formatString.ToUpper().Equals("R")) {
Byte value = (Byte) obj;
int remainder;
int result;
String returnString = String.Empty;
// Get the hundreds digit(s)
result = Math.DivRem(value, 100, out remainder);
if (result > 0)
returnString = new String('C', result);
value = (Byte) remainder;
// Get the 50s digit
result = Math.DivRem(value, 50, out remainder);
if (result == 1)
returnString += "L";
value = (Byte) remainder;
// Get the tens digit.
result = Math.DivRem(value, 10, out remainder);
if (result > 0)
returnString += new String('X', result);
value = (Byte) remainder;
// Get the fives digit.
result = Math.DivRem(value, 5, out remainder);
if (result > 0)
returnString += "V";
value = (Byte) remainder;
// Add the ones digit.
if (remainder > 0)
returnString += new String('I', remainder);
// Check whether we have too many X characters.
int pos = returnString.IndexOf("XXXX");
if (pos >= 0) {
int xPos = returnString.IndexOf("L");
if (xPos >= 0 & xPos == pos - 1)
returnString = returnString.Replace("LXXXX", "XC");
else
returnString = returnString.Replace("XXXX", "XL");
}
// Check whether we have too many I characters
pos = returnString.IndexOf("IIII");
if (pos >= 0)
if (returnString.IndexOf("V") >= 0)
returnString = returnString.Replace("VIIII", "IX");
else
returnString = returnString.Replace("IIII", "IV");
return returnString;
}
// Use default for all other formatting.
if (obj is IFormattable)
return ((IFormattable) obj).ToString(format, CultureInfo.CurrentCulture);
else
return obj.ToString();
}
}
public class Example
{
public static void Main()
{
int n = 10;
double value = 16.935;
DateTime day = DateTime.Now;
InterceptProvider provider = new InterceptProvider();
Console.WriteLine(String.Format(provider, "{0:N0}: {1:C2} on {2:d}\n", n, value, day));
Console.WriteLine(String.Format(provider, "{0}: {1:F}\n", "Today: ",
(DayOfWeek) DateTime.Now.DayOfWeek));
Console.WriteLine(String.Format(provider, "{0:X}, {1}, {2}\n",
(Byte) 2, (Byte) 12, (Byte) 199));
Console.WriteLine(String.Format(provider, "{0:R}, {1:R}, {2:R}\n",
(Byte) 2, (Byte) 12, (Byte) 199));
}
}
// The example displays the following output:
// Provider: InterceptProvider, Object: 10, Format String: N0
// Provider: InterceptProvider, Object: 16.935, Format String: C2
// Provider: InterceptProvider, Object: 1/31/2013 6:10:28 PM, Format String: d
// 10: $16.94 on 1/31/2013
//
// Provider: InterceptProvider, Object: Today: , Format String: <null>
// Provider: InterceptProvider, Object: Thursday, Format String: F
// Today: : Thursday
//
// Provider: InterceptProvider, Object: 2, Format String: X
// Provider: InterceptProvider, Object: 12, Format String: <null>
// Provider: InterceptProvider, Object: 199, Format String: <null>
// 2, 12, 199
//
// Provider: InterceptProvider, Object: 2, Format String: R
// Provider: InterceptProvider, Object: 12, Format String: R
// Provider: InterceptProvider, Object: 199, Format String: R
// II, XII, CXCIX
open System
open System.Globalization
type InterceptProvider() =
interface IFormatProvider with
member this.GetFormat(formatType) =
if formatType = typeof<ICustomFormatter> then
this
else
null
interface ICustomFormatter with
member _.Format(format, obj, provider: IFormatProvider) =
// Display information about method call.
let formatString =
if format = null then "<null>" else format
printfn $"Provider: {provider.GetType().Name}, Object: %A{obj}, Format String: %s{formatString}"
if obj = null then
String.Empty
else
// If this is a byte and the "R" format string, format it with Roman numerals.
match obj with
| :? byte as value when formatString.ToUpper().Equals "R" ->
let mutable returnString = String.Empty
// Get the hundreds digit(s)
let struct (result, remainder) = Math.DivRem(value, 100uy)
if result > 0uy then
returnString <- String('C', int result)
let value = byte remainder
// Get the 50s digit
let struct (result, remainder) = Math.DivRem(value, 50uy)
if result = 1uy then
returnString <- returnString + "L"
let value = byte remainder
// Get the tens digit.
let struct (result, remainder) = Math.DivRem(value, 10uy)
if result > 0uy then
returnString <- returnString + String('X', int result)
let value = byte remainder
// Get the fives digit.
let struct (result, remainder) = Math.DivRem(value, 5uy)
if result > 0uy then
returnString <- returnString + "V"
let value = byte remainder
// Add the ones digit.
if remainder > 0uy then
returnString <- returnString + String('I', int remainder)
// Check whether we have too many X characters.
let pos = returnString.IndexOf "XXXX"
if pos >= 0 then
let xPos = returnString.IndexOf "L"
returnString <-
if xPos >= 0 && xPos = pos - 1 then
returnString.Replace("LXXXX", "XC")
else
returnString.Replace("XXXX", "XL")
// Check whether we have too many I characters
let pos = returnString.IndexOf "IIII"
if pos >= 0 then
returnString <-
if returnString.IndexOf "V" >= 0 then
returnString.Replace("VIIII", "IX")
else
returnString.Replace("IIII", "IV")
returnString
// Use default for all other formatting.
| :? IFormattable as x ->
x.ToString(format, CultureInfo.CurrentCulture)
| _ ->
string obj
let n = 10
let value = 16.935
let day = DateTime.Now
let provider = InterceptProvider()
String.Format(provider, "{0:N0}: {1:C2} on {2:d}\n", n, value, day)
|> printfn "%s"
String.Format(provider, "{0}: {1:F}\n", "Today: ", DateTime.Now.DayOfWeek)
|> printfn "%s"
String.Format(provider, "{0:X}, {1}, {2}\n", 2uy, 12uy, 199uy)
|> printfn "%s"
String.Format(provider, "{0:R}, {1:R}, {2:R}\n", 2uy, 12uy, 199uy)
|> printfn "%s"
// The example displays the following output:
// Provider: InterceptProvider, Object: 10, Format String: N0
// Provider: InterceptProvider, Object: 16.935, Format String: C2
// Provider: InterceptProvider, Object: 1/31/2013 6:10:28 PM, Format String: d
// 10: $16.94 on 1/31/2013
//
// Provider: InterceptProvider, Object: Today: , Format String: <null>
// Provider: InterceptProvider, Object: Thursday, Format String: F
// Today: : Thursday
//
// Provider: InterceptProvider, Object: 2, Format String: X
// Provider: InterceptProvider, Object: 12, Format String: <null>
// Provider: InterceptProvider, Object: 199, Format String: <null>
// 2, 12, 199
//
// Provider: InterceptProvider, Object: 2, Format String: R
// Provider: InterceptProvider, Object: 12, Format String: R
// Provider: InterceptProvider, Object: 199, Format String: R
// II, XII, CXCIX
Imports System.Globalization
Public Class InterceptProvider : Implements IFormatProvider, ICustomFormatter
Public Function GetFormat(formatType As Type) As Object _
Implements IFormatProvider.GetFormat
If formatType Is GetType(ICustomFormatter) Then
Return Me
Else
Return Nothing
End If
End Function
Public Function Format(fmt As String, obj As Object, provider As IFormatProvider) As String _
Implements ICustomFormatter.Format
Dim formatString As String = If(fmt IsNot Nothing, fmt, "<null>")
Console.WriteLine("Provider: {0}, Object: {1}, Format String: {2}",
provider, If(obj IsNot Nothing, obj, "<null>"), formatString)
If obj Is Nothing Then Return String.Empty
' If this is a byte and the "R" format string, format it with Roman numerals.
If TypeOf(obj) Is Byte AndAlso formatString.ToUpper.Equals("R") Then
Dim value As Byte = CByte(obj)
Dim remainder As Integer
Dim result As Integer
Dim returnString As String = String.Empty
' Get the hundreds digit(s)
result = Math.DivRem(value, 100, remainder)
If result > 0 Then returnString = New String("C"c, result)
value = CByte(remainder)
' Get the 50s digit
result = Math.DivRem(value, 50, remainder)
If result = 1 Then returnString += "L"
value = CByte(remainder)
' Get the tens digit.
result = Math.DivRem(value, 10, remainder)
If result > 0 Then returnString += New String("X"c, result)
value = CByte(remainder)
' Get the fives digit.
result = Math.DivRem(value, 5, remainder)
If result > 0 Then returnString += "V"
value = CByte(remainder)
' Add the ones digit.
If remainder > 0 Then returnString += New String("I"c, remainder)
' Check whether we have too many X characters.
Dim pos As Integer = returnString.IndexOf("XXXX")
If pos >= 0 Then
Dim xPos As Integer = returnString.IndexOf("L")
If xPos >= 0 And xPos = pos - 1 Then
returnString = returnString.Replace("LXXXX", "XC")
Else
returnString = returnString.Replace("XXXX", "XL")
End If
End If
' Check whether we have too many I characters
pos = returnString.IndexOf("IIII")
If pos >= 0 Then
If returnString.IndexOf("V") >= 0 Then
returnString = returnString.Replace("VIIII", "IX")
Else
returnString = returnString.Replace("IIII", "IV")
End If
End If
Return returnString
End If
' Use default for all other formatting.
If obj Is GetType(IFormattable)
Return CType(obj, IFormattable).ToString(fmt, CultureInfo.CurrentCulture)
Else
Return obj.ToString()
End If
End Function
End Class
Module Example
Public Sub Main()
Dim n As Integer = 10
Dim value As Double = 16.935
Dim day As DateTime = Date.Now
Dim provider As New InterceptProvider()
Console.WriteLine(String.Format(provider, "{0:N0}: {1:C2} on {2:d}", n, value, day))
Console.WriteLine()
Console.WriteLine(String.Format(provider, "{0}: {1:F}", "Today",
CType(Date.Now.DayOfWeek, DayOfWeek)))
Console.WriteLine()
Console.WriteLine(String.Format(provider, "{0:X}, {1}, {2}\n",
CByte(2), CByte(12), CByte(199)))
Console.WriteLine()
Console.WriteLine(String.Format(provider, "{0:R}, {1:R}, {2:R}",
CByte(2), CByte(12), CByte(199)))
End Sub
End Module
' The example displays the following output:
' Provider: InterceptProvider, Object: 10, Format String: N0
' Provider: InterceptProvider, Object: 16.935, Format String: C2
' Provider: InterceptProvider, Object: 1/31/2013 6:10:28 PM, Format String: d
' 10: $16.94 on 1/31/2013
'
' Provider: InterceptProvider, Object: Today: , Format String: <null>
' Provider: InterceptProvider, Object: Thursday, Format String: F
' Today: : Thursday
'
' Provider: InterceptProvider, Object: 2, Format String: X
' Provider: InterceptProvider, Object: 12, Format String: <null>
' Provider: InterceptProvider, Object: 199, Format String: <null>
' 2, 12, 199
'
' Provider: InterceptProvider, Object: 2, Format String: R
' Provider: InterceptProvider, Object: 12, Format String: R
' Provider: InterceptProvider, Object: 199, Format String: R
' II, XII, CXCIX
자주 묻는 질문(FAQ)
String.Format 메서드 호출에 대해 문자열 보간을 권장하는 이유는 무엇인가요?
문자열 보간은 다음과 같습니다.
- 더 유연합니다. 복합 서식을 지원하는 메서드를 호출할 필요 없이 문자열에서 사용할 수 있습니다. 그렇지 않으면 Format 메서드 또는 복합 서식을 지원하는 다른 메서드(예: Console.WriteLine 또는 StringBuilder.AppendFormat)를 호출해야 합니다.
- 더 읽기 쉬움. 문자열에 삽입할 식이 인수 목록이 아닌 보간된 식에 표시되므로 보간된 문자열은 코딩 및 읽기가 더 쉽습니다. 보간된 문자열을 문자열 연결 작업에 사용하여 보다 간결하고 명확한 코드를 생성할 수도 있습니다.
다음 두 코드 예제를 비교하면 문자열 연결과 복합 서식 지정 메서드 호출보다 보간된 문자열의 우위를 보여 줍니다. 다음 예제에서는 여러 문자열 연결 작업을 사용하여 코드가 장황해지고 읽기 어려워집니다.
string[] names = { "Balto", "Vanya", "Dakota", "Samuel", "Koani", "Yiska", "Yuma" };
string output = names[0] + ", " + names[1] + ", " + names[2] + ", " +
names[3] + ", " + names[4] + ", " + names[5] + ", " +
names[6];
output += "\n";
var date = DateTime.Now;
output += String.Format("It is {0:t} on {0:d}. The day of the week is {1}.",
date, date.DayOfWeek);
Console.WriteLine(output);
// The example displays the following output:
// Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
// It is 10:29 AM on 1/8/2018. The day of the week is Monday.
open System
let names = [| "Balto"; "Vanya"; "Dakota"; "Samuel"; "Koani"; "Yiska"; "Yuma" |]
let output =
names[0] + ", " + names[1] + ", " + names[2] + ", " +
names[3] + ", " + names[4] + ", " + names[5] + ", " +
names[6] + "\n"
let date = DateTime.Now
output + String.Format("It is {0:t} on {0:d}. The day of the week is {1}.", date, date.DayOfWeek)
|> printfn "%s"
// The example displays the following output:
// Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
// It is 10:29 AM on 1/8/2018. The day of the week is Monday.
Module Example12
Public Sub Main()
Dim names = {"Balto", "Vanya", "Dakota", "Samuel", "Koani", "Yiska", "Yuma"}
Dim output = names(0) + ", " + names(1) + ", " + names(2) + ", " +
names(3) + ", " + names(4) + ", " + names(5) + ", " +
names(6)
output += vbCrLf
Dim dat = DateTime.Now
output += String.Format("It is {0:t} on {0:d}. The day of the week is {1}.",
dat, dat.DayOfWeek)
Console.WriteLine(output)
End Sub
End Module
' The example displays the following output:
' Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
' It is 10:29 AM on 1/8/2018. The day of the week is Monday.
반면, 다음 예제에서 보간된 문자열을 사용하면 문자열 연결 문과 이전 예제의 Format 메서드 호출보다 훨씬 더 명확하고 간결한 코드를 생성합니다.
string[] names = { "Balto", "Vanya", "Dakota", "Samuel", "Koani", "Yiska", "Yuma" };
string output = $"{names[0]}, {names[1]}, {names[2]}, {names[3]}, {names[4]}, " +
$"{names[5]}, {names[6]}";
var date = DateTime.Now;
output += $"\nIt is {date:t} on {date:d}. The day of the week is {date.DayOfWeek}.";
Console.WriteLine(output);
// The example displays the following output:
// Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
// It is 10:29 AM on 1/8/2018. The day of the week is Monday.
open System
let names = [| "Balto"; "Vanya"; "Dakota"; "Samuel"; "Koani"; "Yiska"; "Yuma" |]
let output = $"{names[0]}, {names[1]}, {names[2]}, {names[3]}, {names[4]}, {names[5]}, {names[6]}"
let date = DateTime.Now
output + $"\nIt is {date:t} on {date:d}. The day of the week is {date.DayOfWeek}."
|> printfn "%s"
// The example displays the following output:
// Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
// It is 10:29 AM on 1/8/2018. The day of the week is Monday.
Module Example13
Public Sub Main()
Dim names = {"Balto", "Vanya", "Dakota", "Samuel", "Koani", "Yiska", "Yuma"}
Dim output = $"{names(0)}, {names(1)}, {names(2)}, {names(3)}, {names(4)}, " +
$"{names(5)}, {names(6)}"
Dim dat = DateTime.Now
output += $"{vbCrLf}It is {dat:t} on {dat:d}. The day of the week is {dat.DayOfWeek}."
Console.WriteLine(output)
End Sub
End Module
' The example displays the following output:
' Balto, Vanya, Dakota, Samuel, Koani, Yiska, Yuma
' It is 10:29 AM on 1/8/2018. The day of the week is Monday.
미리 정의된 형식 문자열은 어디에서 찾을 수 있나요?
- 모든 정수 및 부동 소수점 형식은 표준 숫자 서식 문자열 사용자 지정 숫자 서식 문자열 참조하세요.
- 날짜 및 시간 값은 표준 날짜 및 시간 형식 문자열 사용자 지정 날짜 및 시간 서식 문자열 참조하세요.
- 열거형 값은 열거형 형식 문자열참조하세요.
- TimeSpan 값은 표준 TimeSpan 형식 문자열 및 사용자 지정 TimeSpan 형식 문자열를 참조하세요.
- Guid 값은 Guid.ToString(String) 참조 페이지의 주의 섹션을 참조하세요.
형식 항목을 대체하는 결과 문자열의 맞춤을 제어하려면 어떻게 해야 하나요?
형식 항목의 일반적인 구문은 다음과 같습니다.
{index[,width][: formatString]}
width 는 필드 너비를 정의하는 부호 있는 정수입니다. 이 값이 음수이면 필드의 텍스트가 왼쪽 맞춤됩니다. 양수이면 텍스트가 오른쪽 맞춤됩니다.
소수 구분 기호 뒤의 자릿수를 제어하려면 어떻게 해야 하나요?
모든 표준 숫자 형식 문자열은 "D"(정수에만 사용), "G", "R", 및 "X"를 제외하고, 결과 문자열의 소수 자릿수를 정의하는 정밀도 지정자를 허용합니다. 다음 예제에서는 표준 숫자 형식 문자열을 사용하여 결과 문자열의 소수 자릿수를 제어합니다.
object[] values = { 1603, 1794.68235, 15436.14 };
string result;
foreach (var value in values)
{
result = String.Format("{0,12:C2} {0,12:E3} {0,12:F4} {0,12:N3} {1,12:P2}\n",
Convert.ToDouble(value), Convert.ToDouble(value) / 10000);
Console.WriteLine(result);
}
// The example displays output like the following:
// $1,603.00 1.603E+003 1603.0000 1,603.000 16.03 %
//
// $1,794.68 1.795E+003 1794.6824 1,794.682 17.95 %
//
// $15,436.14 1.544E+004 15436.1400 15,436.140 154.36 %
open System
let values: obj list = [ 1603, 1794.68235, 15436.14 ]
for value in values do
String.Format("{0,12:C2} {0,12:E3} {0,12:F4} {0,12:N3} {1,12:P2}\n", Convert.ToDouble(value), Convert.ToDouble(value) / 10000.)
|> printfn "%s"
// The example displays output like the following:
// $1,603.00 1.603E+003 1603.0000 1,603.000 16.03 %
//
// $1,794.68 1.795E+003 1794.6824 1,794.682 17.95 %
//
// $15,436.14 1.544E+004 15436.1400 15,436.140 154.36 %
Module Example7
Public Sub Main()
Dim values() As Object = {1603, 1794.68235, 15436.14}
Dim result As String
For Each value In values
result = String.Format("{0,12:C2} {0,12:E3} {0,12:F4} {0,12:N3} {1,12:P2}",
value, CDbl(value) / 10000)
Console.WriteLine(result)
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' $1,603.00 1.603E+003 1603.0000 1,603.000 16.03 %
'
' $1,794.68 1.795E+003 1794.6824 1,794.682 17.95 %
'
' $15,436.14 1.544E+004 15436.1400 15,436.140 154.36 %
사용자 지정 숫자 서식 문자열사용하는 경우 다음 예제와 같이 "0" 형식 지정자를 사용하여 결과 문자열의 소수 자릿수를 제어합니다.
decimal value = 16309.5436m;
string result = String.Format("{0,12:#.00000} {0,12:0,000.00} {0,12:000.00#}",
value);
Console.WriteLine(result);
// The example displays the following output:
// 16309.54360 16,309.54 16309.544
let value = 16309.5436m
String.Format("{0,12:#.00000} {0,12:0,000.00} {0,12:000.00#}", value)
|> printfn "%s"
// The example displays the following output:
// 16309.54360 16,309.54 16309.544
Module Example8
Public Sub Main()
Dim value As Decimal = 16309.5436D
Dim result As String = String.Format("{0,12:#.00000} {0,12:0,000.00} {0,12:000.00#}",
value)
Console.WriteLine(result)
End Sub
End Module
' The example displays the following output:
' 16309.54360 16,309.54 16309.544
정수 자릿수를 제어하려면 어떻게 해야 하나요?
기본적으로 서식 지정 작업에는 0이 아닌 정수만 표시됩니다. 정수의 서식을 지정하는 경우 전체 자릿수 지정자를 "D" 및 "X" 표준 서식 문자열과 함께 사용하여 숫자 수를 제어할 수 있습니다.
int value = 1326;
string result = String.Format("{0,10:D6} {0,10:X8}", value);
Console.WriteLine(result);
// The example displays the following output:
// 001326 0000052E
open System
let value = 1326
String.Format("{0,10:D6} {0,10:X8}", value)
|> printfn "%s"
// The example displays the following output:
// 001326 0000052E
Module Example10
Public Sub Main()
Dim value As Integer = 1326
Dim result As String = String.Format("{0,10:D6} {0,10:X8}", value)
Console.WriteLine(result)
End Sub
End Module
' The example displays the following output:
' 001326 0000052E
다음 예제와 같이 "0" 사용자 지정 숫자 형식 지정자사용하여 정수 또는 부동 소수점 숫자를 선행 0으로 채워 지정된 수의 정수로 결과 문자열을 생성할 수 있습니다.
int value = 16342;
string result = String.Format("{0,18:00000000} {0,18:00000000.000} {0,18:000,0000,000.0}",
value);
Console.WriteLine(result);
// The example displays the following output:
// 00016342 00016342.000 0,000,016,342.0
open System
let value = 16342
String.Format("{0,18:00000000} {0,18:00000000.000} {0,18:000,0000,000.0}", value)
|> printfn "%s"
// The example displays the following output:
// 00016342 00016342.000 0,000,016,342.0
Module Example9
Public Sub Main()
Dim value As Integer = 16342
Dim result As String = String.Format("{0,18:00000000} {0,18:00000000.000} {0,18:000,0000,000.0}",
value)
Console.WriteLine(result)
End Sub
End Module
' The example displays the following output:
' 00016342 00016342.000 0,000,016,342.0
서식 목록에 포함할 수 있는 항목은 몇 개입니까?
실질적인 제한은 없습니다. Format(IFormatProvider, String, Object[]) 메서드의 두 번째 매개 변수는 ParamArrayAttribute 특성으로 태그가 지정되므로 구분된 목록 또는 개체 배열을 서식 목록으로 포함할 수 있습니다.
결과 문자열에 리터럴 중괄호("{" 및 "}")를 포함하려면 어떻게 해야 하나요?
예를 들어 다음 메서드 호출이 FormatException 예외를 throw하지 않도록 하려면 어떻게 해야 할까요?
result = String.Format("The text has {0} '{' characters and {1} '}' characters.",
nOpen, nClose);
let result =
String.Format("The text has {0} '{' characters and {1} '}' characters.", nOpen, nClose)
result = String.Format("The text has {0} '{' characters and {1} '}' characters.",
nOpen, nClose)
단일 여는 중괄호 또는 닫는 중괄호는 항상 형식 항목의 시작 또는 끝으로 해석됩니다. 문자 그대로 해석되려면 이스케이프되어야 합니다. 다음 메서드 호출과 같이 "{" 및 "}" 대신 다른 중괄호("{{" 및 "}}")를 추가하여 중괄호를 이스케이프합니다.
string result;
int nOpen = 1;
int nClose = 2;
result = String.Format("The text has {0} '{{' characters and {1} '}}' characters.",
nOpen, nClose);
Console.WriteLine(result);
let result =
String.Format("The text has {0} '{{' characters and {1} '}}' characters.", nOpen, nClose)
result = String.Format("The text has {0} '{{' characters and {1} '}}' characters.",
nOpen, nClose)
그러나 이스케이프된 중괄호조차도 쉽게 잘못 해석됩니다. 다음 예제와 같이 서식 목록에 중괄호를 포함하고 서식 항목을 사용하여 결과 문자열에 삽입하는 것이 좋습니다.
string result;
int nOpen = 1;
int nClose = 2;
result = String.Format("The text has {0} '{1}' characters and {2} '{3}' characters.",
nOpen, "{", nClose, "}");
Console.WriteLine(result);
let result =
String.Format("The text has {0} '{1}' characters and {2} '{3}' characters.", nOpen, "{", nClose, "}")
result = String.Format("The text has {0} '{1}' characters and {2} '{3}' characters.",
nOpen, "{", nClose, "}")
String.Format 메서드를 호출하면 FormatException이 throw되는 이유는 무엇인가요?
예외의 가장 일반적인 원인은 서식 항목의 인덱스가 서식 목록의 개체에 해당하지 않는다는 것입니다. 일반적으로 형식 항목의 인덱스를 잘못 열거했거나 서식 목록에 개체를 포함하는 것을 잊어버렸습니다. 이스케이프되지 않은 왼쪽 또는 오른쪽 중괄호 문자를 포함하려고 하면 FormatException예외가 발생합니다. 경우에 따라 예외는 오타의 결과입니다. 예를 들어 일반적인 실수는 "{"(왼쪽 중괄호) 대신 "["(왼쪽 대괄호)를 잘못 입력하는 것입니다.
Format(System.IFormatProvider,System.String,System.Object[]) 메서드가 매개 변수 배열을 지원하는 경우 배열을 사용할 때 내 코드가 예외를 throw하는 이유는 무엇인가요?
예를 들어 다음 코드는 FormatException 예외를 throw합니다.
Random rnd = new Random();
int[] numbers = new int[4];
int total = 0;
for (int ctr = 0; ctr <= 2; ctr++)
{
int number = rnd.Next(1001);
numbers[ctr] = number;
total += number;
}
numbers[3] = total;
Console.WriteLine($"{numbers} + {1} + {2} = {3}");
open System
let rnd = Random()
let mutable total = 0
let numbers = Array.zeroCreate<int> 4
for i = 0 to 2 do
let number = rnd.Next 1001
numbers[i] <- number
total <- total + number
numbers[3] <- total
Console.WriteLine("{0} + {1} + {2} = {3}", numbers)
Imports System.Collections.Generic
Module Example5
Public Sub Main()
Dim rnd As New Random()
Dim numbers(3) As Integer
Dim total As Integer = 0
For ctr = 0 To 2
Dim number As Integer = rnd.Next(1001)
numbers(ctr) = number
total += number
Next
numbers(3) = total
Console.WriteLine("{0} + {1} + {2} = {3}", numbers)
End Sub
End Module
컴파일러 오버로드 해석의 문제입니다. 컴파일러는 정수 배열을 개체 배열로 변환할 수 없으므로 정수 배열을 단일 인수로 처리하므로 Format(String, Object) 메서드를 호출합니다. 형식 목록에는 하나의 항목만 있는데 4개의 형식 항목이 있어 예외가 발생합니다.
Visual Basic과 C#은 모두 정수 배열을 개체 배열로 변환할 수 없으므로 Format(String, Object[]) 메서드를 호출하기 전에 직접 변환을 수행해야 합니다. 다음 예제에서는 하나의 구현을 제공합니다.
Random rnd = new Random();
int[] numbers = new int[4];
int total = 0;
for (int ctr = 0; ctr <= 2; ctr++)
{
int number = rnd.Next(1001);
numbers[ctr] = number;
total += number;
}
numbers[3] = total;
object[] values = new object[numbers.Length];
numbers.CopyTo(values, 0);
Console.WriteLine($"{values} + {1} + {2} = {3}");
open System
let rnd = Random()
let numbers = Array.zeroCreate<int> 4
let mutable total = 0
for i = 0 to 2 do
let number = rnd.Next 1001
numbers[i] <- number
total <- total + number
numbers[3] <- total
let values = Array.zeroCreate<obj> numbers.Length
numbers.CopyTo(values, 0)
Console.WriteLine("{0} + {1} + {2} = {3}", values)
Imports System.Collections.Generic
Module Example6
Public Sub Main()
Dim rnd As New Random()
Dim numbers(3) As Integer
Dim total As Integer = 0
For ctr = 0 To 2
Dim number As Integer = rnd.Next(1001)
numbers(ctr) = number
total += number
Next
numbers(3) = total
Dim values(numbers.Length - 1) As Object
numbers.CopyTo(values, 0)
Console.WriteLine("{0} + {1} + {2} = {3}", values)
End Sub
End Module
.NET