String and character literals (C++)
How to declare and define string and character literals in C++.
docs.microsoft.com
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*, encoded as UTF-8
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*, encoded as UTF-8
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
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*, encoded as UTF-8
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, 넓은 범위 문자 utf16,utf32 인코딩과 같은 제각각의 u8, L, u 접두사를 사용합니다. 저수준 문자열 리터럴은 이러한 인코딩의 저 수준으로 대응되는 r, u8r, lr, ur과 같은 접두사를 갖을 수 있습니다. 임시거나 정적 std::string 값을 만들기 위해서 당신은 문자열 리터럴 또는 저수준 리터럴을 s 접미사와 같이 쓸 수 있습니다. 더 많은 정보는 아래에 String Literals를 보세요. 더 많은 기본 문자열 집합이나 유니버스 문자열 이름, 당신 소스코드에 확장된 코드페이지 캐릭터 사용에 대한 것은 Character sets를 보세요.
Character Literals
캐릭터 리터럴은 상수 캐릭터로 구성됩니다. 이것은 따옴표에 둘러쌓인 문자들로 표현됩니다. 다섯가지 종류의 문자 리터럴이 있습니다.
- char의 오리지널 문자 리터럴, 예시 'a'
- char(C++20에서는 char8_t) 타입의 utf8 문자 리터럴, 예시 u8'a'
- wchar_t 의 넓은 문자 리터럴, 예시 L'a'
- char16_t의 utf-16 문자 리터럴, 예시 u'a'
- char32_t의 utf-32 문자 리터럴, 예시 U'a'
문자 리터럴에 사용되는 문자는 예약된 \,', 뉴라인을 제외하면 어떤 문자도 될수 있다. 예약된 문자들은 이스케이프 시퀀스로 지정될 수 있다. 문자들 범용문자 이름으로 지정된다. 그 타입이 문자를 포함할 만큼 충분히 크다면.
인코딩
문자 리터럴은 그들의 접두사를 기반으로 다르게 인코딩됩니다.
- 접두사가 없는 문자는 오리지널 문자 리터럴 입니다. 문자셋 실행에서 표현되는 싱글 문자나, 이스케이프 문자 또는 범용 문자 이름을 포함하는 문자 리터럴의 오리지널 값은 문자셋 실행에서 인코딩의 숫자값과 동일합니다. 하나 이상 문자, 이스케이프시퀀스 또는 범용 문자 이름을 포함하는 오리지널 문자는 멀티문자 리터럴입니다. 실행 문자 세트에서 표현할 수 없는 멀티 문자 리터럴 또는 일반 문자 리터럴은 type int 와 이며 그 값은 구현 정의 입니다. MSVC에 대해서는 아래 Microsoft-specific section을 보세요.
- 접두사 L로 시작하는 캐릭터 리터럴은 광범위한 문자 리터럴이다. 싱글 문자, 이스케이프 시퀀스, 범용 문자 이름을 포함하는 광범위한 문자 리터럴 값은 문자 리터럴이 와이드 문자셋에서 표현되지 않는한 와이드 캐릭터 문자셋 실행에서 인코딩 수치 값과 동일합니다. 단 이경우 값은 구현정의됩니다.멀티 문자들과 이스케이프 시퀀스 또는 범용 캐릭터 이름을 포함하는 와이드 캐릭터 문자열의 값은 구현정의입니다. MSVC에 대해서는 아래 Microsoft-specific 섹션을 보세요.
- u8 접두사로 시작하는 문자 리터럴은 utf8 문자 리터럴이다. 싱글 문자, 이스케이프 시퀀스 또는 범용 캐릭터 이름을 포함하는 utf8 문자 리터럴 값은 utf8 코드 단독 코드 단위로 표현된다면 iso 10646 코드 포인트와 동일한 값을 갖는다. (C0 Control 과 기본 라틴 유니코드 블록에 해당). 단독 utf8 코드 단위로 표현되지 않는 값은 잘못된 형식입니다. 하나 이상의 문자, 이스케이프 시퀀스, 범용 문자 이름을 포함하는 utf8 문자 리터럴은 잘못된 형식입니다.
- u 접두사로 시작하는 문자 리터럴은 utf16 문자 리터럴이다. 단독 문자, 이스케이프 시퀀스, 또는 범용 캐릭터 이름을 포함하는 utf16값은 iso 10646 코드 포인트와 동등하다. 만약 그것이 단독 utf16코드 단위로 표현되었다면. (기본 멀티 2중 언어 플레인에 대응하는) 만약 그 값이 단독 utf16 코드 단위르롤 표현하지 않는다면 그것은 잘못된 형식이다. 하나의 이상의 문자, 이스케이프 문자열 또는 범용 문자 이름을 포함하는 utf16문자 리터럴은 잘못된 형식이다.
- U 접두사로 시작하는 문자 리터럴은 utf-32 문자 리터럴이다. 단독 문자, 이스케이프 시퀀스, 범용 문자 이름을 포함하는 utf32 문자 리터럴 값은 iso 10646 코드 포인트 값과 동일하다. 하나 이상의 문자, 이스케이프 시퀀스, 범용 문자 이름을 포함하는 utf32 문자 리터럴은 잘못된 형식이다.
Escape sequences
세 종류의 이스케이프 시퀀스가 있다. simple, octal, and hexidecimal. 이스케이프 시퀀스는 다음값 중 하나가 될 수 있다.
newline | \n |
backslash | \\ |
horizontal tab | \t |
question mark | ? or \? |
vertical tab | \v |
single quote | \' |
backspace | \b |
double quote | \" |
carriage return | \r |
the null character | \0 |
form feed | \f |
octal | \ooo |
alert (bell) | \a |
hexadecimal | \xhhh |
octal 이스케이프 시퀀스는 백슬래쉬 이후의 하나에서 세개의 8진수가 나오는 시퀀스이다. octal 이스케이프 시퀀스는 세번째 진수 전에 8진수가 아닌 문자를 만난다 면 그 처음 문자에서 종료됩니다. 8진수 값의 가장 큰값은 \377입니다.
16진수 이스케이프 시퀀스는 백슬래쉬 다음에 x 그 다음에 하나 이상의 16진수가 옵니다. 앞의 0은 무시된다. 일반문자나 u8 접두사 캐릭터 리터럴에서 최대 16진수 값은 0xFF이다. L 또는 u 넓은 캐릭터 리터럴에서의 최대 16진수 값은 0xFFFF 이다. U 접두사 넓은 캐릭터 맅럴에서 최대 16진수 값은 0xFFFFFF이다.
다음 샘플 코드는 일반문자 리터럴을 사용하는 이스케이프 캐릭터 예제를 보여준다. 다른 문자 리터럴 타입에도 동일한 이스케이프 시퀀스 구분은 유효합니다.
#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
*/
백슬래쉬 문자는 라인 끝에 위치 하면 라인 지속 문자인다. 만약 당신이 백슬래쉬를 캐릭터 리터럴로 표현하길 원한다면 당신은 반드시 행에 2개의 백슬래쉬를 사용해요한다. 라인 지속 문자에 대해 더 알고 싶으면 봐라 Phase of Thranslation
마이크로소프트 관련
좁은 멀티문자 리터럴에서 값을 만들기 위해서는 컴파일러는 문자나 문자 시퀀스를 반점 사이에서 32bit integer에서 8bit로 변경합니다. 리터럴에 멀티 문자는 높은 순에서 낮은순으로 요구되는 바이트에 대응하여 채웁니다. 그리고 컴파일러는 정수형을 보통의 규칙에 따라 목적지 타입으로 변경합니다. 예를 들어 char 값을 만들기 위해서 컴파일러는 낮은 순서의 byte를 갖습니다. 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'
\377보다 더 큰 8진수 이스케이프 시퀀수는 에러 c2022를 발생합니다. '10진수값":매우 큰 문자.
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
마이크로 소프트 관련 섹션은 여기 맨 끝에
범용 문자 이름들
문자 리터럴과 네이티브 문자열 리터럴에서 어떤 문자나 범용 문자 이름을 나타낼 수 있다. 범용 문자 이름은 \U 접두사를 갖고 그 다음 8진수 유니코드 포인트가 오거나 \u접두사를 갖고 그다음 4진수 유니코드 포인트가 오는 형식을 갖는다. 모든 8진수 4진수는 개별적으로 더 나은 유니버셜 문자 이름 형식을 만들기 위해 제시된다.
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
대리 페어
범용 문자 이름은 대리 코드 포인트 범위 D8000-DFFF에서 값을 인코드 하지 않습니다. 유니코드 대리 쌍에서 특히 \UNNNNNNNN을 사용한 범용문자이름에서 NNNNNNNN은 문자에 대한 8진수 코드 입니다. 컴파일러는 필요하다면 대리 페어를 생성합니다.
C++ 03에서 일부 문자에만 범용문자이름을 나타나 내느 것을 허용 했고 일부 범용문자이름은 실제로 일부 적합한 유니코드 문자들을 표현하는 것이 불가능합니다. 이런 실수는 c++11 기준에 수정되었습니다. C++11에서는 문자 그리고 문자열 리터럴 그리고 식별자까지 모두 범용 문자 이름을 사용할 수 있습니다. 범용문자이름에 대한 더 많은 정보는 CharacterSets을 참고하세요. 유니코드에 대한 정보는 Unicode를 보세요. 대리쌍에 대한 더많은 정보는 Surrogate Pairs and Supplementary Characters를 보세요.
'English > Development' 카테고리의 다른 글
MSDN_C++LanguageReference_User-defined Literals (0) | 2021.09.07 |
---|---|
MSDN_C++LanguageReference_String and character literals#2 (0) | 2021.09.06 |
MSDN_C++LanguageReference_Numeric,Boolean,and Pointer literals (0) | 2021.08.24 |
MSDN_C++LanguageReference_Punctunators(C++) (0) | 2021.08.23 |
MSDN_C++LanguageReference_Keywords(C++) (0) | 2021.08.20 |