이스케이프 시퀀스

이스케이프 시퀀스 (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-0x1F0x7F-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" 범주로 제한되었음 어떤 범주의 별명도 사용 가능

더 알아보기 (Learn more)