문자열 및 문자 리터럴(C++)
C++를 사용하면 다양한 문자열 및 문자 형식이 지원되며 이러한 각 형식의 리터럴 값을 표현할 수 있습니다. 소스 코드에서는 문자 집합을 사용하여 문자 및 문자열 리터럴의 내용을 표현합니다. 유니버설 문자 이름 및 이스케이프 문자를 사용하면 기본 소스 문자 집합만 사용하여 모든 문자열을 표현할 수 있습니다. 원시 문자열 리터럴을 사용하면 이스케이프 문자를 사용하지 않아도 되며 원시 문자열 리터럴을 사용하여 모든 유형의 문자열 리터럴을 표현할 수 있습니다. 추가 생성 또는 변환 단계를 수행할 필요 없이 리터럴을 만들 std::string
수도 있습니다.
#include <string>
using namespace std::string_literals; // enables s-suffix for std::string literals
int main()
{
// Character literals
auto c0 = 'A'; // char
auto c1 = u8'A'; // char
auto c2 = L'A'; // wchar_t
auto c3 = u'A'; // char16_t
auto c4 = U'A'; // char32_t
// Multicharacter literals
auto m0 = 'abcd'; // int, value 0x61626364
// String literals
auto s0 = "hello"; // const char*
auto s1 = u8"hello"; // const char* before C++20, encoded as UTF-8,
// const char8_t* in C++20
auto s2 = L"hello"; // const wchar_t*
auto s3 = u"hello"; // const char16_t*, encoded as UTF-16
auto s4 = U"hello"; // const char32_t*, encoded as UTF-32
// Raw string literals containing unescaped \ and "
auto R0 = R"("Hello \ world")"; // const char*
auto R1 = u8R"("Hello \ world")"; // const char* before C++20, encoded as UTF-8,
// const char8_t* in C++20
auto R2 = LR"("Hello \ world")"; // const wchar_t*
auto R3 = uR"("Hello \ world")"; // const char16_t*, encoded as UTF-16
auto R4 = UR"("Hello \ world")"; // const char32_t*, encoded as UTF-32
// Combining string literals with standard s-suffix
auto S0 = "hello"s; // std::string
auto S1 = u8"hello"s; // std::string before C++20, std::u8string in C++20
auto S2 = L"hello"s; // std::wstring
auto S3 = u"hello"s; // std::u16string
auto S4 = U"hello"s; // std::u32string
// Combining raw string literals with standard s-suffix
auto S5 = R"("Hello \ world")"s; // std::string from a raw const char*
auto S6 = u8R"("Hello \ world")"s; // std::string from a raw const char* before C++20, encoded as UTF-8,
// std::u8string in C++20
auto S7 = LR"("Hello \ world")"s; // std::wstring from a raw const wchar_t*
auto S8 = uR"("Hello \ world")"s; // std::u16string from a raw const char16_t*, encoded as UTF-16
auto S9 = UR"("Hello \ world")"s; // std::u32string from a raw const char32_t*, encoded as UTF-32
}
문자열 리터럴에는 각각 좁은 문자(싱글 바이트 또는 멀티 바이트), UTF-8, 와이드 문자(UCS-2 또는 UTF-16), UTF-16 및 UTF-32 인코딩을 나타내는 접두사 또는 u8
접 L
u
U
두사를 가질 수 없습니다. 원시 문자열 리터럴에는 이러한 인코딩에 해당하는 원시 버전에 대한 접두사, , 및 접두사를 가질 R
uR
u8R
LR
수 있습니다.UR
임시 또는 정적 std::string
값을 만들려면 접미사와 함께 문자열 리터럴 또는 원시 문자열 리터럴을 s
사용할 수 있습니다. 자세한 내용은 아래의 String 리터럴 섹션을 참조하세요. 기본 소스 문자 집합, 범용 문자 이름 및 소스 코드의 확장된 코드 페이지의 문자 사용에 대한 자세한 내용은 문자 집합을 참조하세요.
문자 리터럴
문자 리터럴 은 상수 문자로 구성됩니다. 작은따옴표로 둘러싸인 문자로 표시됩니다. 문자 리터럴에는 5가지 종류가 있습니다.
형식
char
의 일반 문자 리터럴(예:'a'
예를 들어 형식의
char
UTF-8 문자 리터럴(char8_t
C++20)u8'a'
wchar_t
형식의 와이드 문자 리터럴(예:L'a'
)형식
char16_t
의 UTF-16 문자 리터럴(예:u'a'
형식
char32_t
의 UTF-32 문자 리터럴(예:U'a'
문자 리터럴에 사용되는 문자는 예약된 문자 백슬래시(), 작은따옴표'
(\
) 또는 줄 바꿈을 제외한 모든 문자일 수 있습니다. 예약된 문자는 이스케이프 시퀀스를 사용하여 지정할 수 있습니다. 문자는 형식이 문자를 저장할 수 있을 만큼 큰 경우 유니버설 문자 이름을 사용하여 지정할 수 있습니다.
인코딩
문자 리터럴은 접두사를 기반으로 다르게 인코딩됩니다.
접두사 없는 문자 리터럴은 일반 문자 리터럴입니다. 실행 문자 집합에 나타낼 수 있는 단일 문자, 이스케이프 시퀀스 또는 범용 문자 이름을 포함하는 일반 문자 리터럴의 값은 실행 문자 집합에서 인코딩의 숫자 값과 같은 값을 줍니다. 둘 이상의 문자, 이스케이프 시퀀스 또는 범용 문자 이름을 포함하는 일반 문자 리터럴은 다중 문자 리터럴입니다. 실행 문자 집합에 나타낼 수 없는 다중 문자 리터럴 또는 일반 문자 리터럴에는 형식
int
이 있으며 해당 값은 구현 정의입니다. MSVC의 경우 아래의 Microsoft 관련 섹션을 참조하세요.접두사로
L
시작하는 문자 리터럴은 와이드 문자 리터럴입니다. 단일 문자, 이스케이프 시퀀스 또는 유니버설 문자 이름을 포함하는 와이드 문자 리터럴의 값은 실행 와이드 문자 집합에 문자 리터럴이 표현되지 않는 한 실행 와이드 문자 집합에서 인코딩의 숫자 값과 같은 값을 하며, 이 경우 값은 구현 정의됩니다. 여러 문자, 이스케이프 시퀀스 또는 범용 문자 이름을 포함하는 와이드 문자 리터럴의 값은 구현에서 정의됩니다. MSVC의 경우 아래의 Microsoft 관련 섹션을 참조하세요.접두사로
u8
시작하는 문자 리터럴은 UTF-8 문자 리터럴입니다. 단일 문자, 이스케이프 시퀀스 또는 범용 문자 이름을 포함하는 UTF-8 문자 리터럴 값은 단일 UTF-8 코드 단위(C0 컨트롤 및 기본 라틴어 유니코드 블록에 해당)로 나타낼 수 있는 경우 ISO 10646 코드 포인트 값과 같은 값을 가집니다. 값을 단일 UTF-8 코드 단위로 나타낼 수 없는 경우 프로그램이 잘못된 형식입니다. 둘 이상의 문자, 이스케이프 시퀀스 또는 범용 문자 이름을 포함하는 UTF-8 문자 리터럴의 형식이 잘못되었습니다.접두사로
u
시작하는 문자 리터럴은 UTF-16 문자 리터럴입니다. 단일 문자, 이스케이프 시퀀스 또는 범용 문자 이름을 포함하는 UTF-16 문자 리터럴 값은 단일 UTF-16 코드 단위(기본 다국어 평면에 해당)로 나타낼 수 있는 경우 해당 ISO 10646 코드 포인트 값과 같은 값을 가집니다. 단일 UTF-16 코드 단위로 값을 나타낼 수 없는 경우 프로그램의 형식이 잘못되었습니다. 둘 이상의 문자, 이스케이프 시퀀스 또는 범용 문자 이름을 포함하는 UTF-16 문자 리터럴의 형식이 잘못되었습니다.접두사로
U
시작하는 문자 리터럴은 UTF-32 문자 리터럴입니다. 단일 문자, 이스케이프 시퀀스 또는 범용 문자 이름을 포함하는 UTF-32 문자 리터럴의 값은 ISO 10646 코드 포인트 값과 같은 값을 가집니다. 둘 이상의 문자, 이스케이프 시퀀스 또는 범용 문자 이름을 포함하는 UTF-32 문자 리터럴의 형식이 잘못되었습니다.
이스케이프 시퀀스
이스케이프 시퀀스는 단순, 8진수 및 16진수의 세 종류가 있습니다. 이스케이프 시퀀스는 다음 값 중 어느 것이든 될 수 있습니다.
값 | 이스케이프 시퀀스 |
---|---|
줄 바꿈 | \n |
백슬래시 | \\ |
가로 탭 | \t |
물음표 | ? 또는\? |
세로 탭 | \v |
작은따옴표 | \' |
백스페이스 | \b |
큰따옴표 | \" |
캐리지 리턴 | \r |
null 문자 | \0 |
폼 피드 | \f |
8진수 | \ooo |
경고(벨) | \a |
16진수 | \xhhh |
8진수 이스케이프 시퀀스는 백슬래시 뒤에 1~3개의 8진수 시퀀스입니다. 8진수 이스케이프 시퀀스는 8진수가 아닌 첫 번째 문자에서 종료됩니다(세 번째 숫자보다 빨리 발생하는 경우). 가능한 가장 높은 8진수 값은 \377
.
16진수 이스케이프 시퀀스는 백슬래시 뒤에 문자 x
가 뒤에 16진수로 구성된 시퀀스입니다. 앞에 오는 0은 무시됩니다. 일반 또는 u8 접두사 문자 리터럴에서 가장 높은 16진수 값은 0xFF. L 접두사 또는 u 접두사가 있는 와이드 문자 리터럴에서 가장 큰 16진수 값은 0xFFFF입니다. U 접두사가 있는 와이드 문자 리터럴에서 가장 큰 16진수 값은 0xFFFFFFFF입니다.
이 샘플 코드는 일반 문자 리터럴을 사용하는 이스케이프된 문자의 몇 가지 예를 보여 줍니다. 동일한 이스케이프 시퀀스 구문은 다른 문자 리터럴 형식에 유효합니다.
#include <iostream>
using namespace std;
int main() {
char newline = '\n';
char tab = '\t';
char backspace = '\b';
char backslash = '\\';
char nullChar = '\0';
cout << "Newline character: " << newline << "ending" << endl;
cout << "Tab character: " << tab << "ending" << endl;
cout << "Backspace character: " << backspace << "ending" << endl;
cout << "Backslash character: " << backslash << "ending" << endl;
cout << "Null character: " << nullChar << "ending" << endl;
}
/* Output:
Newline character:
ending
Tab character: ending
Backspace character:ending
Backslash character: \ending
Null character: ending
*/
백슬래시 문자(\
)는 줄 끝에 배치되는 줄 연속 문자입니다. 백슬래시 문자가 문자 리터럴로 표시되도록 하려면 두 개의 백슬래시(\\
)를 연속하여 입력해야 합니다. 줄 연속 문자에 대한 자세한 내용은 Phases of Translation를 참조하세요.
Microsoft 전용
좁은 다중 문자 리터럴에서 값을 만들기 위해 컴파일러는 작은따옴표 사이의 문자 또는 문자 시퀀스를 32비트 정수 내의 8비트 값으로 변환합니다. 리터럴의 여러 문자는 필요에 따라 상위에서 하위로 해당 바이트를 채웁니다. 그런 다음 컴파일러는 일반적인 규칙에 따라 정수를 대상 형식으로 변환합니다. 예를 들어 값을 만들기 char
위해 컴파일러는 낮은 순서의 바이트를 사용합니다. wchar_t
또는 char16_t
값을 만들기 위해 컴파일러는 하위 단어를 사용합니다. 컴파일러는 비트가 할당된 바이트 또는 단어 이상으로 설정된 경우 결과가 잘린다고 경고합니다.
char c0 = 'abcd'; // C4305, C4309, truncates to 'd'
wchar_t w0 = 'abcd'; // C4305, C4309, truncates to '\x6364'
int i0 = 'abcd'; // 0x61626364
3자리 이상의 숫자를 포함하는 것처럼 보이는 8진수 이스케이프 시퀀스는 3자리 8진수 시퀀스로 처리되고, 그 다음에는 후속 숫자가 다자문자 리터럴의 문자로 처리되므로 놀라운 결과를 얻을 수 있습니다. 예시:
char c1 = '\100'; // '@'
char c2 = '\1000'; // C4305, C4309, truncates to '0'
8진수가 아닌 문자를 포함하는 것처럼 보이는 이스케이프 시퀀스는 마지막 8진수 문자까지의 8진수 시퀀스로 평가되고, 뒤에 다시 기본 문자가 다문자 리터럴의 후속 문자로 계산됩니다. 첫 번째 8진수가 아닌 문자가 10진수이면 경고 C4125가 생성됩니다. 예시:
char c3 = '\009'; // '9'
char c4 = '\089'; // C4305, C4309, truncates to '9'
char c5 = '\qrs'; // C4129, C4305, C4309, truncates to 's'
오류 C2022: 'value-in-decimal'을 발생시키는 것보다 \377
높은 값을 갖는 8진수 이스케이프 시퀀스: 문자에 비해 너무 큽다.
16진수 및 16진수 이스케이프 문자가 있는 것처럼 보이는 이스케이프 시퀀스는 마지막 16진수 문자까지 16진수 이스케이프 시퀀스를 포함하는 다자문자 리터럴로 평가되고 그 뒤에 16진수 문자가 잇습니다. 16진수 숫자가 없는 16진수 이스케이프 시퀀스는 컴파일러 오류 C2153을 발생시킵니다. "16진수 리터럴에는 16진수 이상이 있어야 합니다.".
char c6 = '\x0050'; // 'P'
char c7 = '\x0pqr'; // C4305, C4309, truncates to 'r'
접두사로 접두 L
사로 지정된 와이드 문자 리터럴이 다자간 시퀀스를 포함하는 경우 값은 첫 번째 문자에서 가져온 것이고 컴파일러는 경고 C4066을 발생합니다. 후속 문자는 동일한 일반 다중 문자 리터럴의 동작과 달리 무시됩니다.
wchar_t w1 = L'\100'; // L'@'
wchar_t w2 = L'\1000'; // C4066 L'@', 0 ignored
wchar_t w3 = L'\009'; // C4066 L'\0', 9 ignored
wchar_t w4 = L'\089'; // C4066 L'\0', 89 ignored
wchar_t w5 = L'\qrs'; // C4129, C4066 L'q' escape, rs ignored
wchar_t w6 = L'\x0050'; // L'P'
wchar_t w7 = L'\x0pqr'; // C4066 L'\0', pqr ignored
Microsoft 관련 섹션은 여기에서 끝납니다.
유니버설 문자 이름
문자 리터럴 및 네이티브(비 원시) 문자열 리터럴에서는 유니버설 문자 이름으로 모든 문자를 나타낼 수 있습니다. 유니버설 문자 이름은 접두 \U
사 뒤에 8자리 유니코드 코드 포인트 또는 접두 \u
사 뒤에 네 자리 유니코드 코드 포인트로 구성됩니다. 올바른 형식의 유니버설 문자 이름을 만들려면 모든 8자리 또는 4자리 숫자가 각각 있어야 합니다.
char u1 = 'A'; // 'A'
char u2 = '\101'; // octal, 'A'
char u3 = '\x41'; // hexadecimal, 'A'
char u4 = '\u0041'; // \u UCN 'A'
char u5 = '\U00000041'; // \U UCN 'A'
서로게이트 쌍
유니버설 문자 이름은 서로게이트 코드 포인트 범위 D800-DFFF의 값을 인코딩할 수 없습니다. 유니코드 서로게이트 쌍에 대해 \UNNNNNNNN
을 사용하여 유니버설 문자 이름을 지정합니다. 여기서 NNNNNNNN은 문자에 대한 8자리 코드 포인트입니다. 컴파일러는 필요한 경우 서로게이트 쌍을 생성합니다.
C++03에서 언어는 문자의 하위 집합만 해당 범용 문자 이름으로 나타낼 수 있도록 허용했으며 실제로 유효한 유니코드 문자를 나타내지 않는 일부 범용 문자 이름을 허용했습니다. 이 실수는 C++11 표준에서 수정되었습니다. C++11에서는 문자 및 문자열 리터럴과 식별자 모두 유니버설 문자 이름을 사용할 수 있습니다. 유니버설 문자 이름에 대한 자세한 내용은 Character Sets을 참조하세요. 유니코드에 대한 자세한 내용은 유니코드(영문)를 참조하세요. 서로게이트 쌍에 대한 자세한 내용은 서로게이트 쌍 및 보조 문자(영문)를 참조하세요.
문자열 리터럴
문자열 리터럴은 함께 사용되어 null로 끝나는 문자열을 형성하는 문자 시퀀스를 나타냅니다. 문자를 큰따옴표로 묶어야 합니다. 다음과 같은 종류의 문자열 리터럴이 있습니다.
좁은 문자열 리터럴
좁은 문자열 리터럴은 접두사로 구분된 큰따옴표로 구분된 null로 끝나는 형식 const char[n]
배열입니다. 여기서 n은 배열의 길이(바이트)입니다. 좁은 문자열 리터럴에는 큰따옴표("
), 백슬래시(\
) 또는 줄 바꿈 문자를 제외한 모든 그래픽 문자가 포함될 수 있습니다. 또한 좁은 문자열 리터럴에는 위에 나열된 이스케이프 시퀀스 및 바이트 크기에 맞는 유니버설 문자 이름이 포함될 수 있습니다.
const char *narrow = "abcd";
// represents the string: yes\no
const char *escaped = "yes\\no";
UTF-8로 인코딩된 문자열
UTF-8로 인코딩된 문자열은 u8 접두사로 구분된 큰따옴표로 구분된 null로 끝나는 형식 const char[n]
배열입니다. 여기서 n 은 인코딩된 배열의 길이(바이트)입니다. u8 접두사가 있는 문자열 리터럴에는 큰따옴표("
), 백슬래시(\
) 또는 줄 바꿈 문자를 제외한 모든 그래픽 문자가 포함될 수 있습니다. 또한 u8 접두사가 있는 문자열 리터럴에는 위에 나열된 이스케이프 시퀀스 및 모든 유니버설 문자 이름이 포함될 수 있습니다.
C++20에는 이식 가능한 char8_t
(UTF-8로 인코딩된 8비트 유니코드) 문자 형식이 도입되었습니다. C++20 u8
에서 리터럴 접두사는 대신 문자 또는 문자열을 지정합니다 char8_t
char
.
// Before C++20
const char* str1 = u8"Hello World";
const char* str2 = u8"\U0001F607 is O:-)";
// C++20 and later
const char8_t* u8str1 = u8"Hello World";
const char8_t* u8str2 = u8"\U0001F607 is O:-)";
와이드 문자열 리터럴
와이드 문자열 리터럴은 null로 끝나는 상수 wchar_t
배열로, 접두사로 'L
'이며 큰따옴표(), 백슬래시("
\
) 또는 줄 바꿈 문자를 제외한 모든 그래픽 문자를 포함합니다. 와이드 문자열 리터럴에는 위에 나열된 이스케이프 시퀀스 및 모든 유니버설 문자 이름이 포함될 수 있습니다.
const wchar_t* wide = L"zyxw";
const wchar_t* newline = L"hello\ngoodbye";
char16_t 및 char32_t(C++11)
C++11에서는 이식 가능한 char16_t
(16비트 유니코드) 및 char32_t
(32비트 유니코드) 문자 형식이 도입되었습니다.
auto s3 = u"hello"; // const char16_t*
auto s4 = U"hello"; // const char32_t*
원시 문자열 리터럴(C++11)
원시 문자열 리터럴은 큰따옴표(), 백슬래시\
("
) 또는 줄 바꿈 문자를 비롯한 그래픽 문자를 포함하는 모든 문자 형식의 null로 끝나는 배열입니다. 원시 문자열 리터럴은 문자 클래스를 사용하는 정규식과 HTML 문자열 및 XML 문자열에 종종 사용됩니다. 예제를 보려면 Bjarne Stroustrup의 C++11에 대한 FAQ(영문) 문서를 참조하세요.
// represents the string: An unescaped \ character
const char* raw_narrow = R"(An unescaped \ character)";
const wchar_t* raw_wide = LR"(An unescaped \ character)";
const char* raw_utf8a = u8R"(An unescaped \ character)"; // Before C++20
const char8_t* raw_utf8b = u8R"(An unescaped \ character)"; // C++20
const char16_t* raw_utf16 = uR"(An unescaped \ character)";
const char32_t* raw_utf32 = UR"(An unescaped \ character)";
구분 기호는 원시 문자열 리터럴의 여는 괄호 바로 앞에 닫는 괄호 바로 뒤에 오는 최대 16자의 사용자 정의 시퀀스입니다. 예를 들어 R"abc(Hello"\()abc"
에서 구분 기호 시퀀스는 abc
이고 문자열 콘텐츠는 Hello"\(
입니다. 구분 기호를 사용하여 큰따옴표와 괄호를 모두 포함하는 원시 문자열을 구분할 수 있습니다. 이 문자열 리터럴은 컴파일러 오류를 발생합니다.
// meant to represent the string: )"
const char* bad_parens = R"()")"; // error C2059
그러나 구분 기호를 사용하면 오류가 해결됩니다.
const char* good_parens = R"xyz()")xyz";
원본에서 줄 바꿈(이스케이프된 문자 아님)을 포함하는 원시 문자열 리터럴을 생성할 수 있습니다.
// represents the string: hello
//goodbye
const wchar_t* newline = LR"(hello
goodbye)";
std::string 리터럴(C++14)
std::string
리터럴은 사용자 정의 리터럴(아래 참조)의 표준 라이브러리 구현으로, s
접미사가 있는 것으로 "xyz"s
표시됩니다. 이러한 종류의 문자열 리터럴은 지정된 접두사에 따라 형식std::string
, std::wstring
std::u32string
또는 std::u16string
형식의 임시 개체를 생성합니다. 위와 같이 접두사를 사용하지 않으면 생성 std::string
됩니다. L"xyz"s
는 .를 std::wstring
생성합니다. u"xyz"s
는 std::u16string을 생성하고 U"xyz"s
std::u32string을 생성합니다.
//#include <string>
//using namespace std::string_literals;
string str{ "hello"s };
string str2{ u8"Hello World" }; // Before C++20
u8string u8str2{ u8"Hello World" }; // C++20
wstring str3{ L"hello"s };
u16string str4{ u"hello"s };
u32string str5{ U"hello"s };
s
접미사는 원시 문자열 리터럴에서도 사용할 수 있습니다.
u32string str6{ UR"(She said "hello.")"s };
std::string
리터럴은 문자열> 헤더 파일의 네임스페이<스에 std::literals::string_literals
정의됩니다. std::literals::string_literals
및 std::literals
가 모두 인라인 네임스페이스로 선언되기 때문에 std::literals::string_literals
는 자동으로 네임스페이스 std
에 직접 속한 것처럼 처리됩니다.
문자열 리터럴의 크기
ANSI char*
문자열 및 기타 단일 바이트 인코딩(UTF-8은 아님)의 경우 문자열 리터럴의 크기(바이트)는 종료 null 문자에 1을 더한 문자 수입니다. 다른 모든 문자열 형식의 경우 크기는 문자 수와 엄격하게 관련되지 않습니다. UTF-8은 최대 4개의 char
요소를 사용하여 일부 코드 단위char16_t
를 인코딩하거나 wchar_t
UTF-16으로 인코딩하면 두 요소(총 4바이트)를 사용하여 단일 코드 단위를 인코딩할 수 있습니다. 이 예제에서는 와이드 문자열 리터럴의 크기(바이트)를 보여 줍니다.
const wchar_t* str = L"Hello!";
const size_t byteSize = (wcslen(str) + 1) * sizeof(wchar_t);
strlen()
wcslen()
종결 null 문자의 크기는 문자열 형식의 요소 크기(a 또는 string의 경우 1바이트, 2 char*
바이트 wchar_t*
또는 char16_t*
char8_t*
문자열, 문자열의 경우 4바이트char32_t*
)는 포함하지 않습니다.
Visual Studio 2022 버전 17.0 이전의 Visual Studio 버전에서 문자열 리터럴의 최대 길이는 65,535바이트입니다. 이 제한은 좁은 문자열 리터럴과 와이드 문자열 리터럴 모두에 적용됩니다. Visual Studio 2022 버전 17.0 이상에서는 이 제한이 해제되고 문자열 길이가 사용 가능한 리소스에 의해 제한됩니다.
문자열 리터럴 수정
문자열 리터럴(리터럴 포함 std::string
안 됨)은 상수이므로 수정 str[2] = 'A'
하려고 하면 컴파일러 오류가 발생합니다.
Microsoft 전용
Microsoft C++에서 문자열 리터럴을 사용하여 비 const char
또는 wchar_t
.에 대한 포인터를 초기화할 수 있습니다. 이 비 const 초기화는 C99 코드에서 허용되지만 C++98에서는 더 이상 사용되지 않으며 C++11에서 제거됩니다. 문자열을 수정하려고 하면 다음 예제와 같이 액세스 위반이 발생합니다.
wchar_t* str = L"hello";
str[2] = L'a'; // run-time error: access violation
(문자열 리터럴 형식 변환 사용 안 함) 컴파일러 옵션을 설정할 /Zc:strictStrings
때 문자열 리터럴이 비 const 문자 포인터로 변환될 때 컴파일러가 오류를 발생시킬 수 있습니다. 표준 준수 이식 가능 코드에 사용하는 것이 좋습니다. 또한 올바른(const) 형식으로 확인되므로 키워드(keyword) 사용하여 auto
문자열 리터럴 초기화된 포인터를 선언하는 것이 좋습니다. 예를 들어 다음 코드 예제는 컴파일 시간에 문자열 리터럴에 쓰려는 시도를 catch합니다.
auto str = L"hello";
str[2] = L'a'; // C3892: you cannot assign to a variable that is const.
경우에 따라 실행 파일의 공간을 절약하기 위해 동일한 문자열 리터럴이 풀링될 수 있습니다. 문자열 리터럴 풀링에서 컴파일러는 각 참조가 문자열 리터럴의 별도 인스턴스를 가리키는 것이 아니라 특정 문자열 리터럴에 대한 모든 참조가 메모리의 같은 위치를 가리키게 합니다. 문자열 풀링을 사용하도록 설정하려면 컴파일러 옵션을 사용합니다 /GF
.
Microsoft 관련 섹션은 여기에서 끝납니다.
인접 문자열 리터럴 연결
인접하는 와이드 문자열 리터럴 또는 좁은 문자열 리터럴은 연결됩니다. 다음 선언은
char str[] = "12" "34";
다음 선언과 동일합니다.
char atr[] = "1234";
또한 다음 선언과 동일합니다.
char atr[] = "12\
34";
포함된 16진수 이스케이프 코드를 사용하여 문자열 리터럴을 지정하면 예기치 않은 결과가 발생할 수 있습니다. 다음 예제는 ASCII 5 문자와 f, i, v 및 e 문자가 포함된 문자열 리터럴을 만들려고 합니다.
"\x05five"
실제 결과는 16진수 5F(ASCII 코드의 밑줄)와 i, v 및 e 문자입니다. 올바른 결과를 얻으려면 다음 이스케이프 시퀀스 중 하나를 사용할 수 있습니다.
"\005five" // Use octal literal.
"\x05" "five" // Use string splicing.
std::string
리터럴(및 관련 std::u8string
, std::u16string
및 std::u32string
)은 형식에 +
대해 정의된 basic_string
연산자와 연결할 수 있습니다. 또한 인접 문자열 리터럴과 동일한 방식으로 연결할 수도 있습니다. 두 경우 모두, 문자열 인코딩과 접미사가 다음과 일치해야 합니다.
auto x1 = "hello" " " " world"; // OK
auto x2 = U"hello" " " L"world"; // C2308: disagree on prefix
auto x3 = u8"hello" " "s u8"world"z; // C3688, disagree on suffixes
유니버설 문자 이름을 가진 문자열 리터럴
네이티브(비 원시) 문자열 리터럴은 문자열 형식에서 하나 이상의 문자로 유니버설 문자 이름을 인코드할 수 있는 한 유니버설 문자 이름을 사용하여 모든 문자를 나타낼 수 있습니다. 예를 들어 확장 문자를 나타내는 범용 문자 이름은 ANSI 코드 페이지를 사용하여 좁은 문자열에서 인코딩할 수 없지만 일부 멀티 바이트 코드 페이지 또는 UTF-8 문자열 또는 와이드 문자열의 좁은 문자열로 인코딩할 수 있습니다. C++11에서 유니코드 지원은 문자열 형식 및 char32_t*
문자열 형식에 의해 char16_t*
확장되고 C++20은 다음 형식으로 char8_t
확장합니다.
// ASCII smiling face
const char* s1 = ":-)";
// UTF-16 (on Windows) encoded WINKING FACE (U+1F609)
const wchar_t* s2 = L"😉 = \U0001F609 is ;-)";
// UTF-8 encoded SMILING FACE WITH HALO (U+1F607)
const char* s3a = u8"😇 = \U0001F607 is O:-)"; // Before C++20
const char8_t* s3b = u8"😇 = \U0001F607 is O:-)"; // C++20
// UTF-16 encoded SMILING FACE WITH OPEN MOUTH (U+1F603)
const char16_t* s4 = u"😃 = \U0001F603 is :-D";
// UTF-32 encoded SMILING FACE WITH SUNGLASSES (U+1F60E)
const char32_t* s5 = U"😎 = \U0001F60E is B-)";