값은 그대로 두고 모양만 바꾼다
앞에서 문자열 보간을 한 줄만 스치고 지나갔습니다.
string msg = $"{name} 님의 점수는 {score}점입니다";
읽기 좋다는 말만 하고 넘어갔는데, 여기에는 두 가지 장치가 들어 있습니다. 값을 끼워 넣는 것과 그 값을 어떤 모양으로 보여줄지 정하는 것입니다. 둘은 다른 일이고, 헷갈리면 앞에서 본 형변환과 뒤섞이게 됩니다.
보간은 이렇게 생겼다
따옴표 앞에 $ 를 붙이면 그 문자열 안에서 중괄호가 특별한 뜻을 갖습니다.
중괄호 안에 적은 것이 값으로 바뀌어 그 자리에 들어갑니다.
string name = "손오공";
int age = 30;
Console.WriteLine($"Name: {name}, Age: {age}"); // Name: 손오공, Age: 30
흔한 실수: $ 를 빼먹는다
$ 가 없으면 중괄호는 그냥 글자입니다.
Console.WriteLine($"Age: {age}"); // Age: 30
Console.WriteLine("Age: {age}"); // Age: {age}
에러가 나지 않고 조용히 글자 그대로 찍히기 때문에, 출력이 이상할 때 가장 먼저 볼 자리입니다.
중괄호 안에는 식도 들어간다
변수 이름만 넣을 수 있는 게 아닙니다. 앞에서 본 대로 식은 값 하나로 줄어드니까, 값 하나로 줄어드는 것이면 무엇이든 들어갑니다.
int a = 3, b = 4;
Console.WriteLine($"합은 {a + b}"); // 합은 7
Console.WriteLine($"{(a > b ? "a 가 큼" : "b 가 큼")}"); // b 가 큼
Console.WriteLine($"이름 길이는 {name.Length}"); // 이름 길이는 3
중괄호 자체를 쓰려면 두 번
중괄호가 특별한 뜻을 가지니, 중괄호 문자 자체가 필요하면 두 번 씁니다. 역슬래시를 두 번 썼던 것과 같은 이유입니다.
Console.WriteLine($"{{{name}}}"); // {손오공}
콜론 뒤는 모양이다
중괄호 안에 콜론을 찍고 형식을 적으면 같은 값이 다른 모양으로 찍힙니다.
double pi = 3.14159265;
Console.WriteLine($"{pi}"); // 3.14159265
Console.WriteLine($"{pi:F2}"); // 3.14
자주 쓰는 것은 이 정도입니다.
| 형식 | 쓰는 법 | 결과 | 쓰임 |
|---|---|---|---|
F2 |
{pi:F2} |
3.14 |
소수점 아래 자릿수 고정 |
N0 |
{amount:N0} |
1,234,567 |
천 단위 쉼표 |
D8 |
{number:D8} |
00001234 |
자릿수 고정, 앞을 0으로 채움 |
P0 |
{rate:P0} |
45% |
백분율 |
C |
{price:C} |
₩1,200 |
통화 |
yyyy-MM-dd |
{today:yyyy-MM-dd} |
2026-09-09 |
날짜 |
F 뒤의 숫자는 소수점 아래 자릿수, D 뒤의 숫자는 전체 자릿수입니다.
C와 날짜 형식은 실행하는 컴퓨터의 지역 설정을 따라갑니다. 같은 코드가 한국에서는₩1,200, 미국에서는$1,200.00으로 찍힐 수 있습니다. 이 차이는 문자열 비교를 볼 때 다시 나옵니다.
값은 바뀌지 않는다
여기가 이 글의 요점입니다. 형식 지정자는 값을 건드리지 않습니다.
double pi = 3.14159265;
Console.WriteLine($"{pi:F0}"); // 3
Console.WriteLine(pi); // 3.14159265 ← 그대로입니다
Console.WriteLine(pi * 2); // 6.2831853 ← 계산도 원래 값으로
앞에서 본 캐스팅과 정반대입니다. 캐스팅은 값을 실제로 잘라냅니다.
(int)pi 를 담은 변수에는 소수부가 아예 없습니다. 되돌릴 수 없습니다.
두 결과가 다른 것도 보입니다. (int) 는 앞에서 본 대로 버림이라 3.7 이 3 이 되고,
F0 은 반올림이라 4 로 보입니다. 하는 일이 아예 다르다는 뜻입니다.
화면에 보여줄 때만 형식 지정자를 쓰고, 값을 실제로 바꿔야 할 때만 캐스팅을 씁니다. 소수 둘째 자리까지만 저장해야 한다면
Math.Round로 값을 바꿔야 하고, 화면에만 그렇게 보이면 되는 것이면F2로 충분합니다.
자리 폭도 정할 수 있다
쉼표 뒤에 숫자를 적으면 그 폭만큼 자리를 잡습니다. 양수면 오른쪽 정렬, 음수면 왼쪽 정렬입니다.
string[] names = { "이름", "손오공", "저팔계" };
string[] scores = { "점수", "95", "7" };
for (int i = 0; i < names.Length; i++)
{
Console.WriteLine($"{names[i],-8}{scores[i],5}");
}
이름 점수
손오공 95
저팔계 7
쉼표와 콜론을 같이 쓸 때는 폭이 먼저, 형식이 나중입니다.
Console.WriteLine($"{price,10:N0}"); // 폭 10칸, 천 단위 쉼표
한글은 글자 하나가 알파벳 두 칸 너비로 보이는데
Length는 1 로 세기 때문에, 한글이 섞인 표는 이 방법으로 딱 맞추기 어렵습니다. 앞에서 본 대로 글자 수와 화면에서 차지하는 너비는 다른 문제입니다.
+ 와 무엇이 다른가
결과는 같습니다. 컴파일러가 보간 문자열을 내부적으로 이어붙이는 코드로 바꿔주기 때문입니다.
그래서 앞에서 본 규칙이 그대로 적용됩니다. 한 줄 안에서 몇 번 이어붙이는 것은 괜찮고,
반복문 안에서 쌓는 것은 여전히 StringBuilder 입니다.
보간을 쓰는 이유는 속도가 아니라 읽기 쉬움입니다.
string a = "[" + level + "] " + name + " (" + score + "점)";
string b = $"[{level}] {name} ({score}점)";
따옴표와 + 를 세어 가며 읽지 않아도 결과 모양이 그대로 보입니다.
정리
$를 붙이면 중괄호 안이 값으로 바뀌어 그 자리에 들어간다.$를 빼먹으면 에러 없이 중괄호가 글자 그대로 찍힌다.- 중괄호 안에는 값 하나로 줄어드는 식이면 무엇이든 들어간다.
- 콜론 뒤에 적는 형식은 보여주는 모양만 정한다. 값은 그대로다.
- 캐스팅은 값을 실제로 자르고, 형식 지정자는 자르지 않는다.
(int)3.7은 3이고{3.7:F0}은 4다. - 쉼표 뒤의 숫자는 자리 폭이다. 음수면 왼쪽 정렬. 폭이 먼저, 형식이 나중이다.
- 보간은
+보다 빠른 게 아니라 읽기 쉬운 것이다. 반복문에서는 여전히StringBuilder.