이스케이프 시퀀스
이스케이프 시퀀스 (Escape Sequences)
문자 리터럴과 문자열 리터럴 안에서 특수 문자를 나타내는 데 쓰는 표기법이에요. 예를 들어 줄바꿈이나 탭 같은 걸 문자 그대로 타이핑할 수 없으니, \n, \t 같은 형태로 적는 거죠.
출처: cppreference
본문
사용 가능한 이스케이프 시퀀스는 다음과 같아요.
| 이스케이프 시퀀스 | 설명 | 표현 |
|---|---|---|
| 단순 이스케이프 시퀀스 | ||
\' |
작은따옴표 | ASCII 인코딩에서 바이트 0x27 |
\" |
큰따옴표 | ASCII 인코딩에서 바이트 0x22 |
\? |
물음표 | ASCII 인코딩에서 바이트 0x3f |
\\ |
백슬래시 | ASCII 인코딩에서 바이트 0x5c |
\a |
경고음 | ASCII 인코딩에서 바이트 0x07 |
\b |
백스페이스 | ASCII 인코딩에서 바이트 0x08 |
\f |
폼 피드 (새 페이지) | ASCII 인코딩에서 바이트 0x0c |
\n |
줄 바꿈 | ASCII 인코딩에서 바이트 0x0a |
\r |
캐리지 리턴 | ASCII 인코딩에서 바이트 0x0d |
\t |
수평 탭 | ASCII 인코딩에서 바이트 0x09 |
\v |
수직 탭 | ASCII 인코딩에서 바이트 0x0b |
| 숫자 이스케이프 시퀀스 | ||
\nnn |
임의의 8진수 값 | 코드 단위 nnn (1~3자리 8진수) |
\o{n...} (C++23) |
코드 단위 n... (임의 개수의 8진수) |
|
\xn... |
임의의 16진수 값 | 코드 단위 n... (임의 개수의 16진수) |
\x{n...} (C++23) |
||
| 조건부 이스케이프 시퀀스[1] | ||
\c |
구현 정의 | 구현 정의 |
| 유니버설 문자 이름 | ||
\unnnn |
임의의 Unicode 값; 여러 코드 단위가 될 수 있음 | 코드 포인트 U+nnnn (4자리 16진수) |
\u{n...} (C++23) |
코드 포인트 U+n... (임의 개수의 16진수) |
|
\Unnnnnnnn |
코드 포인트 U+nnnnnnnn (8자리 16진수) |
|
\N{NAME} (C++23) |
임의의 Unicode 문자 | NAME이 이름인 문자 (아래 참고) |
- [1] 조건부 이스케이프 시퀀스는 조건부로 지원돼요. 각 조건부 이스케이프 시퀀스의 문자
c는 다른 어떤 이스케이프 시퀀스에서\뒤에 오는 문자가 아닌, 기본 소스 문자 집합(C++23 이전) / 기본 문자 집합(C++23 이후)의 멤버예요.
유니버설 문자 이름의 범위
유니버설 문자 이름이 0x24($), 0x40(@), 0x60(`)이 아니면서 0xA0보다 작은 코드 포인트에 대응하면 프로그램은 ill-formed예요. 다시 말해, 기본 소스 문자 집합의 멤버와 제어 문자(범위 0x0-0x1F와 0x7F-0x9F)는 유니버설 문자 이름으로 표현할 수 없어요. (C++11 이전)
기본 소스 문자 집합의 멤버나 제어 문자의 코드 포인트에 대응하는 유니버설 문자 이름이 문자 리터럴이나 문자열 리터럴 밖에 나타나면 프로그램은 ill-formed예요. 유니버설 문자 이름이 서로게이트 코드 포인트(범위 0xD800-0xDFFF)에 대응하면 프로그램은 ill-formed예요. UTF-16/32 문자열 리터럴에 쓰인 유니버설 문자 이름이 ISO/IEC 10646의 코드 포인트(범위 0x0-0x10FFFF)에 대응하지 않으면 프로그램은 ill-formed예요. (C++11 이후, C++20 이전)
기본 소스 문자 집합의 멤버나 제어 문자의 코드 포인트에 대응하는 유니버설 문자 이름이 문자/문자열 리터럴 밖에 나타나면 ill-formed. 유니버설 문자 이름이 ISO/IEC 10646의 코드 포인트(범위 0x0-0x10FFFF)에 대응하지 않거나 서로게이트 코드 포인트(범위 0xD800-0xDFFF)에 대응하면 ill-formed. (C++20 이후, C++23 이전)
기본 문자 집합의 문자의 스칼라 값이나 제어 문자에 대응하는 유니버설 문자 이름이 문자/문자열 리터럴 밖에 나타나면 ill-formed. 유니버설 문자 이름이 번역 문자 집합의 문자의 스칼라 값에 대응하지 않으면 ill-formed. (C++23 이후)
이름 붙은 유니버설 문자 이스케이프
\N{ n-char-sequence }
n-char-sequence— 하나 이상의 n-char. n-char는 번역 문자 집합의 문자로, 오른쪽 중괄호}나 줄 바꿈 문자는 제외.
위 문법의 유니버설 문자 이름은 **이름 붙은 유니버설 문자(named universal character)**예요. n-char-sequence가 그 문자의 이름이나 문자 이름 별명 중 하나와 같으면 Unicode 표준(4.8장 Name)의 해당 문자를 가리켜요. 그렇지 않으면 프로그램은 ill-formed예요.
이 별명들은 Unicode Character Database의 NameAliases.txt에 나열돼 있어요. 이 이름이나 별명 중 어느 것도 앞뒤에 공백이 없어요. 유효한 n-char-sequence는 대문자 라틴 문자 A~Z, 숫자, 공백, 하이픈-마이너스만 포함해야 해요. 다른 문자는 Unicode 문자 이름에 결코 나타나지 않으므로, n-char-sequence에 그런 문자가 등장하면 항상 프로그램을 ill-formed로 만들어요. (C++23 이후)
Notes
\0은 가장 흔히 쓰이는 8진수 이스케이프 시퀀스예요. 널로 끝나는 문자열에서 종료 널 문자를 나타내기 때문이에요.
줄 바꿈 문자 \n은 텍스트 모드 I/O에서 특별한 의미를 가져요. OS 특유의 줄 바꿈 표현(보통 한 바이트 또는 바이트 시퀀스)으로 변환되죠. 어떤 시스템은 대신 길이 필드로 줄을 표시하기도 해요.
8진수 이스케이프 시퀀스는 3자리 8진수로 제한되지만, 그 전에 유효한 8진수 문자가 아닌 것이 나오면 거기서 끝나요. 16진수 이스케이프 시퀀스는 길이 제한이 없고 유효한 16진수 문자가 아닌 첫 문자에서 끝나요. 단일 16진수 이스케이프 시퀀스가 나타내는 값이 그 문자열 리터럴에 쓰인 문자 타입(char, char8_t(C++20), char16_t, char32_t(C++11), 또는 wchar_t)이 나타내는 값의 범위에 안 맞으면 결과는 미지정이에요.
(C++11 이후) 좁은 문자열 리터럴이나 16비트 문자열 리터럴의 유니버설 문자 이름은 여러 코드 단위로 매핑될 수 있어요. 예를 들어 \U0001f34c는 UTF-8에서 4개의 char 코드 단위(\xF0\x9F\x8D\x8C)이고, UTF-16에서 2개의 char16_t 코드 단위(\xD83C\xDF4C)예요.
물음표 이스케이프 시퀀스 \?는 문자열 리터럴 안에서 trigraph가 해석되는 것을 막는 데 쓰였어요. "??/" 같은 문자열은 "\로 컴파일되는데, 두 번째 물음표를 "?\?/"처럼 이스케이프하면 "??/"가 돼요. trigraph가 C++에서 제거되었으므로 물음표 이스케이프 시퀀스는 더 이상 필요하지 않아요. C++14(및 그 이전 개정판)와 C와의 호환성을 위해 남아 있어요. (C++17 이후)
| 기능 테스트 매크로 | 값 | 표준 | 기능 |
|---|---|---|---|
__cpp_named_character_escapes |
202207L |
(C++23) | 이름 붙은 유니버설 문자 이스케이프 |
예제
여기서 확인할 것: \n과 \" 이스케이프가 실제 출력에서 어떻게 보이는지 보는 코드예요.
#include <iostream>
int main()
{
std::cout << "This\nis\na\ntest\n\n";
std::cout << "She said, \"Sells she seashells on the seashore?\"\n";
}
출력:
This
is
a
test
She said, "Sells she seashells on the seashore?"
결함 보고 (Defect reports)
다음의 동작 변경 결함 보고는 이전에 발표된 C++ 표준에 소급 적용됐어요.
| DR | 적용 대상 | 발표 당시 동작 | 올바른 동작 |
|---|---|---|---|
| CWG 505 | C++98 | 백슬래시 뒤의 문자가 표의 문자 중 하나가 아니면 동작이 정의되지 않았음 | 조건부 지원이 됨 (의미는 구현 정의) |
| P3733R1 | C++23 | 이름 붙은 유니버설 문자 이스케이프의 별명이 "control", "correction", "alternate" 범주로 제한되었음 | 어떤 범주의 별명도 사용 가능 |