C/C++ 혹은 JAVA에서는 printf 메서드를 사용하여 %d, %s, %f 등으로 형식을 지정하여 출력하는 이른바 '형식 문자열 출력'을 이용하여 문자열을 출력할 때 형 변환, 번거로운 작업 없이 손 쉽게 출력하는게 가능했습니다.

심지어 파일에 내용을 기록할 때도 사용될만큼 아주 다양한 범위에서 사용되었죠.


.NET에서도 형식 문자열을 출력하는 것을 지원합니다.

C/C++에서 사용하던 %08x %08X 도 동일하게 구현이 가능하구요!

그리고 매우 강한 강점 하나가 바로 자료형에 상관 없이 형식화가 가능하다는 것!


C/C++에서는 문자열은 %s, 문자의 경우 %c 정수는 보통 %d를 사용하고 실수형은 %f를 사용한 반면 .NET에서는 형식에 상관 없이 {#} 형식으로만 써주면 끝입니다!


얼마나 편한가요?

.NET의 강점 중 하나가 자료형에 상관 없이 형식 문자열을 출력할 수 있다는 것을 대표적으로 꼽을 수 있을 만큼 똑똑하고 만족스러운 기능입니다.


그럼 이제 천천히 문자열을 형식화 해보도록 할까요?

이 글에서 다룰 Format 메서드는 문자열과 가변 매개 변수인 params 를 사용하는 메서드입니다.

String.Format 메서드 (MSDN)


형식 문자열(%s, %d 등과 같은)을 지정할 때는 아주 간단하게 순서대로

{0} {1} {2} ... {n}

이렇게 지정해주시면 됩니다.

여기서 꼭 짚고 넘어가야할 것은 전달된 매개 변수의 갯수보다 형식이 지정된 항목의 인덱스가 클 경우 예외가 발생합니다.

반대로 형식이 지정된 항목의 인덱스가 전달된 매개 변수의 갯수보다 작을 경우엔 아무런 상관이 없습니다.

무슨 말인지 이해가 안되신다구요? 코드를 보시죠.

using System;

namespace Formatting {
    class Program {
        public static void Main(string[] args) {
            String formattedText;
            Int32 A = 500;
            Int32 B = 125;
            
            // 문제 없음
            formattedText = String.Format("A is {0} and B is {1}, {0} - {1} is {2}", A, B, A - B);
            Console.WriteLine(formattedText);

            // 문제 없음, 하지만 A - B는 출력되지 않음
            formattedText = String.Format("A is {0} and B is {1}", A, B, A - B);
            Console.WriteLine(formattedText);

            // 예외 발생, 전달된 매개 변수보다 형식이 지정된 항목의 인덱스가 더 높음
            try {
                formattedText = String.Format("A is {0} and B is {1}, {0} - {1} is {2}, {0} / {1} is {3}", A, B, A - B);
                Console.WriteLine(formattedText);
            } catch (Exception ex) {
                Console.WriteLine(ex.Message);
            }
            
            Console.ReadKey(true);
        }
    }
}


그리고 코드의 결과는 이렇게 나오는군요


첫번째 문자열은 모든 값이 그대로 잘 출력된 것을 확인할 수 있구요.

두번째 문자열에서는 A - B 가 출력되지 않았네요.

그리고 마지막 세번째 문자열에선 4번째 항목 {3} 에 대한 매개 변수가 전달되지 않아서 예외가 발생해버렸네요~~


분명 %08x 같은 형식도 지정할 수 있다고 했는데, {0} 이런 식으로는 해당 값만 나오게 되죠.

Tip!

형식을 지정할 때 {0}, {1} 과 같이 아무런 서식을 지정하지 않고 형식을 지정해줄 경우엔 해당 자료형의 ToString() 메서드의 결과 값을 출력합니다.


그럼 어떻게 서식을 지정하는지 한번 알아보도록 하겠습니다.

 서식 

 해당되는 형식

 예제 

 비고

C, c

숫자 형식

 입력 값: 123.456

 "C" - \123

 "C1" - \123.5

 "C3" - \123.456

통화 서식 지정자

D, d

정수 형식 (실수 X)

 입력 값: 123456

 "D" - 123456

 "D3" - 123456

 "D10" - 0000123456

10진수 서식 지정자

E, e

숫자 형식 

 입력 값: 123.456

 "e" - 1.234560E+002
 "E3" - 1.235E+002
 "E10" - 1.2345600100E+002

지수 서식 지정자

F, f

숫자 형식 

 입력 값: 123.456

 "F" - 123.46
 "F3" - 123.456

 "F10" - 123.4560000000 

고정 소숫점 서식 지정자 

G, g

숫자 형식 

 입력 값: 123.456

 "G" - 123.456
 "G3" - 123
 "G10" - 123.456001

일반 서식 지정자 

N, n

숫자 형식 

 입력 값: 123456.789

 "N" - 123,456.80
 "N3" - 123,456.800
 "N10" - 123,456.8000000000

숫자 서식 지정자 

P, p

숫자 형식 

 입력 값: 1

 "P" - 100.00 %
 "P3" - 100.000 %
 "P10" - 100.0000000000 %


 입력 값: 0.314159

 "P" - 31.42 %
 "P3" - 31.416 %
 "P10" - 31.4159000000 %

백분율 서식 지정자

R, r

실수 형식(Single, Double) 및 BigIntger 

 입력 값: 123456.789012
 "R" - 123456.789


 입력 값: 123456789.123456789
 "R" - 123456792

라운드트립 서식 지정자 

이놈이 뭐하는 놈인지 모르겠음

X, x

정수 형식 

 입력 값: 123456
 "X" - 1E240
 "X8" - 0001E240
 "x" - 1e240

16진수 서식 지정자


이 중에서도 굵게 표시된 것들이 가장 많이 사용되는 서식 지정자입니다.

그럼 이런 서식 지정자는 어떻게 적용하느냐?...

방법은 정말 간단합니다.


MSDN에서는 이렇게 표기되어 있습니다.

{ index[,alignment][:formatString]}


이걸 그대로 풀어서 설명하자면 이렇게 됩니다.

{ 인덱스 번호 [, 정렬 방식] [:서식 지정자] }

인덱스 번호는 0, 1, 2, ... ,n 과 같이 몇 번째에 위치한 매개 변수를 형식화하여 출력할 것인지를 결정하는 값입니다.

정렬 방식은 선택적입니다. -20, 20 처럼 사용할 수 있습니다. 더 자세한 내용은 예제를 이용하여 설명하도록 하겠습니다.

서식 지정자 또한 선택적입니다. :D, :X8, :N0 처럼 사용할 수 있습니다. 마찬가지로 예제를 이용하여 설명하도록 하겠습니다.



문자열 형식화 예제 (코드가 분량을 다때먹네요)

using System;
using System.Diagnostics;

namespace Formatting {
    class Program {
        public static void Main(string[] args) {
            Int32 positiveNum = 123456;
            Int32 negativeNum = -123456;
            Single realNumber32 = 123456.789F;
            Double realNumber64 = 123456.789012345;
            String text = "String.Format example";
            
            Console.WriteLine("서식이 지정되지 않은 그대로의 값: ");
            Console.WriteLine("  positiveNum : {0}", positiveNum);
            Console.WriteLine("  negativeNum : {0}", negativeNum);
            Console.WriteLine("  realNumber32: {0}", realNumber32);
            Console.WriteLine("  realNumber64: {0}", realNumber64);
            Console.WriteLine("  text        : {0}", text);
            
            Console.WriteLine("통화 서식이 지정된 값: ");
            Console.WriteLine("  positiveNum : {0:c}", positiveNum);
            Console.WriteLine("  negativeNum : {0:C}", negativeNum);
            Console.WriteLine("  realNumber32: {0:c}", realNumber32);
            Console.WriteLine("  realNumber64: {0:C}", realNumber64);
            Console.WriteLine("  text        : {0:C}", text);
            
            Console.WriteLine("10진수 서식이 지정된 값: ");
            Console.WriteLine("  positiveNum : {0:d}", positiveNum);
            Console.WriteLine("  negativeNum : {0:D}", negativeNum);
            Console.WriteLine("  realNumber32: -");
            Console.WriteLine("  realNumber64: -");
            Console.WriteLine("  text        : {0:D}", text);
            
            Console.WriteLine("고정 소숫점 서식이 지정된 값: ");
            Console.WriteLine("  positiveNum : {0:f}", positiveNum);
            Console.WriteLine("  negativeNum : {0:F}", negativeNum);
            Console.WriteLine("  realNumber32: {0:f}", realNumber32);
            Console.WriteLine("  realNumber64: {0:F}", realNumber64);
            Console.WriteLine("  text        : {0:F}", text);
            
            Console.WriteLine("일반 서식이 지정된 값: ");
            Console.WriteLine("  positiveNum : {0:g}", positiveNum);
            Console.WriteLine("  negativeNum : {0:G}", negativeNum);
            Console.WriteLine("  realNumber32: {0:g}", realNumber32);
            Console.WriteLine("  realNumber64: {0:G}", realNumber64);
            Console.WriteLine("  text        : {0:G}", text);
            
            Console.WriteLine("숫자 서식이 지정된 값: ");
            Console.WriteLine("  positiveNum : {0:n}", positiveNum);
            Console.WriteLine("  negativeNum : {0:N}", negativeNum);
            Console.WriteLine("  realNumber32: {0:n}", realNumber32);
            Console.WriteLine("  realNumber64: {0:N}", realNumber64);
            Console.WriteLine("  text        : {0:N}", text);
            
            Console.WriteLine("백분율 서식이 지정된 값: ");
            Console.WriteLine("  positiveNum : {0:p}", positiveNum);
            Console.WriteLine("  negativeNum : {0:P}", negativeNum);
            Console.WriteLine("  realNumber32: {0:p}", realNumber32);
            Console.WriteLine("  realNumber64: {0:P}", realNumber64);
            Console.WriteLine("  text        : {0:P}", text);
            
            Console.WriteLine("라운드트립 서식이 지정된 값: ");
            Console.WriteLine("  positiveNum : -");
            Console.WriteLine("  negativeNum : -");
            Console.WriteLine("  realNumber32: {0:r}", realNumber32);
            Console.WriteLine("  realNumber64: {0:R}", realNumber64);
            Console.WriteLine("  text        : {0:R}", text);
            
            Console.WriteLine("16진수 서식이 지정된 값: ");
            Console.WriteLine("  positiveNum : {0:x}", positiveNum);
            Console.WriteLine("  negativeNum : {0:X}", negativeNum);
            Console.WriteLine("  realNumber32: -");
            Console.WriteLine("  realNumber64: -");
            Console.WriteLine("  text        : {0:X}", text);
            
            
            Console.ReadKey(true);
        }
    }
}


결과:


여기서 빼먹은 것이 있네요.

정렬은 어떻게 하는지 또 예제로 확인하겠습니다.

using System;
using System.Diagnostics;

namespace Formatting {
    class Program {
        public static void Main(string[] args) {
            Int32 positiveNum0 = 123;
            Int32 positiveNum1 = 1234;
            Int32 positiveNum2 = 12345;
            Int32 positiveNum3 = 123456;
            
            Console.WriteLine("| {0,10:N0} |", positiveNum0);
            Console.WriteLine("| {0,10:N0} |", positiveNum1);
            Console.WriteLine("| {0,10:N0} |", positiveNum2);
            Console.WriteLine("| {0,10:N0} |", positiveNum3);
            Console.WriteLine("| {0,-10:N0} |", positiveNum0);
            Console.WriteLine("| {0,-10:N0} |", positiveNum1);
            Console.WriteLine("| {0,-10:N0} |", positiveNum2);
            Console.WriteLine("| {0,-10:N0} |", positiveNum3);
            Console.ReadKey(true);
        }
    }
}


결과:


정렬할 때 자릿수의 값이 양수인 경우에는 오른쪽으로 # 자리만큼 맞추고,

음수(-)일 경우에는 왼쪽으로 # 자리만큼 맞춥니다.


이렇게 Format 메서드를 이용한 서식, 형식을 지정하는 방법에 대해서 알아봤습니다.

다소 부족하지만, 도움이 되었으면 좋겠습니다.



긴글 읽어주셔서 감사합니다!

+ Recent posts