Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

nomad-programmer

[Programming/C++] 문자열 상수 본문

Programming/C++

[Programming/C++] 문자열 상수

scii 2023. 2. 5. 02:42

때로는 프로그램이 1바이트로 표현할 수 없는 문자 세트(예를 들면 일본어, 중국어, 한국어 문자 세트)를 처리해야 하는 경우도 있다. C++는 이것을 두 가지 방법으로 처리한다.

첫째, 확장 문자 세트가 시스템의 기본 문자 세트이면, 컴파일러 개발업체가 char형을 처음부터 2바이트(16비트) 또는 그 이상으로 만드는 것이다.

둘째, 기본 문자 세트와 확장 문자 세트를 동시에 지원하는 것이다. 즉, 보통의 8비트 char형으로 기본 문자 세트를 나타내고, wchar_t형(wide character type에서 w, char, t를 각각 따 왔다)으로 확장 문자 세트를 나타내는 것이다. wchar_t형은 시스템에서 사용되는 가장 큰 확장 문자 세트를 나타낼 수 있을 만큼의 충분한 비트 폭을 가진 정수형이다. wchar_t형은 기초 데이터형이라고 부르는 정수형과 동일한 크기와 부호 속성을 가진다. 기초 데이터형은 시스템에 따라 다른데, 어떤 시스템에서는 unsigned short형일 수 있고, 다른 시스템에서는 int형이 될 수도 있다.

cin과 cout은 입력과 출력을 char형 문자의 스트림으로 간주하기 때문에 wchar_t형을 처리하지 못한다. 최신 버전의 iostream 헤더 파일은 wchar_t형 문자의 스트림을 처리하기 위해 wcin과 wcout 객체를 제공한다. 그리고 확장 문자 상수나 확장 문자 문자열은 그 앞에 L을 붙여서 나타낸다. 다음과 같은 코드는 변수 bob에 문자 P의 wchar_t형 버전을 저장하고, 단어 tall의 wchar_t형 번전을 디스플레이한다.

wchar_t bob = L'P';       // 확장 문자 상수
wcout << L"tall" << endl;  // 확장 문자 문자열 출력

2바이트 wchar_t형을 사용하는 시스템에서, 이 코드는 각 문자에 2바이트씩 대입하여 메모리에 저장한다. 

국제시장을 겨냥하여 프로그램을 개발하려면 확장 문자 세트를 사용해야 한다.


새로운 C++11형: char16_t와 char32_t

커뮤니티에서 유니코드에 대한 많은 경험들이 공유되면서 wchar_t 변수형만으로는 부족하다는 것이 많이 알려졌다. 컴퓨터 시스템상의 문자나 문자열을 변환하는 것은 단순하게 유니코드 숫자값을 변환하는 것보다 훨씬 복잡한 일이다. 특별한 경우에 문자열을 변환할 때 길이와 부호가 고정될 필요가 있는데, wchar_t의 부호와 길이는 가변이기 때문에 문제가 발생할 수 있다. 그래서 C++11은 unsigned 16비트형인 char_16_t와 unsigned 32비트형인 char32_t를 소개하고 있다. C++11에서 char16_t변수형은 u'C' 또는 u"be good"과 같이 접두사로 u를 사용한다. 이와 유사하게 char32_t 변수형은 U'R' 또는 U"dirtyrat"과 같이 접두사로 U를 사용한다. char16_t형은 /u00F6 형태의 유니버셜 문자 이름과 매칭이 된다. 그리고 char32_t형은 /U0000222B 형태의 유니버셜 문자 이름과 매칭이 된다.

접두사 u와 U는 char16_t와 char32_t 변수형의 문자 상수를 지시할 때 사용된다.

char16_t ch1 = u'q';          // 기본 16비트 문자
char32_t ch2 = U'\U0000222B'  // 32비트 유니버셜 문자 이름

wchar_t, char16_t, char32_t 와 같이 _을 가지고 있는 형들은 정수형의 일종이지만, 시스템마다 다를 수 있다.


다른 형태의 문자열 상수

위에서 언급된 내용이지만, C++은 char형 이외에도 wchar_t형을 가지고 있다. 그리고, C++11에는 char16_t와 char32_t를 추가로 가지고 있으며, 이러한 형들의 배열과 문자열 상수가 가능하다. C++은 문자열 상수를 초기화하기 위해 L, u, U의 접두사를 가지고 있다. 다음은 이러한 접두사들을 어떻게 사용하는지에 대한 예이다.

wchar_t title[] = L"CoreDynamics";    // w_char 문자열
char16_t name[] = u"Ethan";           // char16_t 문자열
char32_t car[] = U"Benz G class";     // char32_t 문자열

C++11은 또한 UTF-8이라고 불리는 유니코드 문자를 위한 인코딩 방법을 지원한다. C++은 UTF-8 형태의 문자열 상수를 나타내기 위해 u8 접두어를 사용한다.

C++11이 지원하는 또 다른 하나를 raw문자열이다. raw 문자열에 있어서 문자들은 독립적으로 존재한다. 예를 들어, \n이 newline 문자로 인식되지 않는다. 대신에 backslash와 n이라는 두 개의 문자로 인식된다. 또 다른 예로, \" 대신에 단순하게 문자열 내에 "를 사용할 수 있다. 문자열 상수 내에 "를 사용할 경우 더 이상 문자열의 끝을 구분할 필요가 없다.

cout << R" ( Jim "King" Tutt uses "\n" instead of endl. ) " << '\n';

// 결과
Jim "King" Tutt uses \n instead of endl.

표준 문자열 상수 선언은 다음과 같다.

cout << "Jim \"King\" Tutt uses \" \\n\" instead of endl." << '\n';

위에서 볼 수 있듯이, \를 출력하기 위해 \\를 사용해야 한다.

만일, raw 문자열을 입력하는 동안에 enter키나 리턴키를 친다면, 모니터상의 커서가 다음 라인으로 이동할 뿐 아니라, raw 문자열 내의 문자도 다음 라인에 자리 잡게 된다.

raw 문자열에서 )"를 출력할 수 있을까? 컴파일러가 )"를 문자열의 끝으로 인식하지는 않을까? raw 문자열 구문은 문자열 시작 부분의 "와 (사이에 문자를 추가 하는 것이 가능하다. 이는 문자열 마지막 부분의 )와 "사이에 똑같은 문자가 추가되어야 한다는 것을 의미하기도 한다. 즉, raw 문자열이 R"+*( 로 시작하면 )+*" 로 마무리되어야 한다.

cout << R"+*("(who wouldn't?)", she whispered.)+*" << endl;

// 결과
"(who wuoldn't?)", she whispered.

간단히 말해서, 기본 구분자 "( 와 )" 는 "+*( 와 )+*" 으로 변환이 된다. 구분자의 하나로 공백이나 왼쪽 괄호, 오른쪽 괄호 백슬래시, 탭 같은 문자들이 아닌 기본 문자 셋의 멤버를 사용할 수도 있다.

접두어 R은 wchar_t 등의 raw 문자열을 생성하기 위해 사용되는 다른 문자열 접두어와 혼용이 가능하다.

Comments