#9. [모던 C++ STL] 문자열
- (C++11~) u16string이 추가되어 UTF-16 인코딩 문자열을 지원합니다.
- (C++11~) u32string이 추가되어 UTF-32 인코딩 문자열을 지원합니다.
- (C++11~) isblank()가 추가되었습니다.
- (C++11~) atoll(), strtoll(), strtoull(), strtoimax(), strtoumax()가 추가되었습니다.
- (C++11~) mbrtoc16(), mbrtoc32(), c32rtomb()가 추가되었습니다.
- (C++11~)
__STDC_UTF_16__
,__STDC_UTF_32__
가 추가되었습니다.- (C++11~) 숫자 변환이 추가되었습니다.
- (C++17~) 숫자와 문자열간의 변환을 위한 to_chars(), from_chars() 함수가 제공되며, 기존 C스타일(atoi(), strtol()등) 보다 안전합니다.
- (C++17~) chars_format이 추가되었습니다.
- (C++20~) u8string이 추가되어 UTF-8 인코딩 문자열을 지원합니다.
- (C++20~) starts_with(), ends_with()가 추가되어 접두사와 접미사를 검사할 수 있습니다.
- (C++20~) mbrtoc8(), c8rtomb()가 추가되었습니다.
개요
문자열을 처리하는 기본 클래스는 basic_string입니다. char_traits
를 사용하여 각 문자 타입별로 문자열을 처리합니다.
항목 | 내용 |
---|---|
basic_string | 문자열의 기본 클래스입니다. |
char_traits |
basic_string에서 각 문자를 처리하는 타입 특성입니다. |
basic_string은 각 타입 별로 별칭을 사용합니다.
항목 | 내용 | 정의 |
---|---|---|
string | 바이트 문자열 | basic_string<char> |
wstring | 와이드 문자열 | basic_string<wchar_t> |
u16string (C++11~) | UTF-16 인코딩 문자열 | basic_string<char16_t> |
u32string (C++11~) | UTF-32 인코딩 문자열 | basic_string<char32_t> |
u8string (C++20~) | UTF-8 인코딩 문자열 | basic_string<char8_t> |
C++11 부터 UTF-16 인코딩을 지원하는 u16string과 UTF-32 인코딩을 지원하는 u32string이 추가되었습니다. 각 요소당 문자 1개를 저장합니다.
1
2
3
4
5
6
7
8
9
std::u16string u16str{u"abc가나다"};
EXPECT_TRUE(u16str == u"abc가나다");
EXPECT_TRUE(u16str.length() == 6);
EXPECT_TRUE(u16str[3] == u'가'); // 각 요소는 문자 1개 입니다.
std::u32string u32str{U"abc가나다"};
EXPECT_TRUE(u32str == U"abc가나다");
EXPECT_TRUE(u32str.length() == 6);
EXPECT_TRUE(u32str[3] == U'가'); // 각 요소는 문자 1개 입니다.
Windows의 경우 와이드 문자열은 내부적으로 UTF-16 인코딩으로 저장되므로(와이드 문자열 참고), u16string과 동일한 코드값을 가지고 있습니다.(Linux는 와이드 문자열이 UTF-32 인코딩을 사용하므로 u32string과 같을 겁니다. 확인해 보지는 않았습니다.)
1
2
3
std::wstring wstr{L"abc가나다"}; // windows에서는 와이드 문자열이 UTF-16으로 저장됩니다.
std::u16string u16str{reinterpret_cast<const char16_t*>(wstr.c_str())}; // 강제적으로 형변환하면 UTF-16과 동일한 형태로 저장되어 있습니다.
EXPECT_TRUE(u16str == u"abc가나다");
C++20 부터는 UTF-8 인코딩을 사용하는 u8string이 추가되었습니다.
wstring, u16string, u32string은 요소 1개당 문자 1개를 저장하지만, u8string은 그렇지 않습니다.
UTF-8 인코딩에서는 문자의 종류에 따라 1 ~ 4byte를 사용하며, 문자가 한글과 같이 3yte인 경우에는 char8_t 타입(적어도 1byte)인 요소 3개로 저장합니다. 따라서 length()
가 문자의 갯수가 아니라 byte의 갯수가 됩니다.
1
2
3
4
5
6
7
std::u8string u8str{u8"abc가나다"};
EXPECT_TRUE(u8str == u8"abc가나다");
EXPECT_TRUE(u8str.length() == 12); // UTF8에서 영문자는 1byte, 한글은 3byte입니다. 한글 1글자를 3개로 처리합니다.
// abc : 3byte, 가 : 3byte, 나 : 3byte, 다 : 3byte
EXPECT_TRUE(u8str[3] == 0xEA); // 한글 '가'는 UTF-8에서 3byte. 0xEA, 0xB0, 0x80
EXPECT_TRUE(u8str[4] == 0xB0);
EXPECT_TRUE(u8str[5] == 0x80);
(C++14~) 표준 사용자 정의 리터럴이 추가되어
operator ""s
,operator ""min
,operator ""if
, 등 문자열, 날짜 / 시간, 복소수 관련 표현이 간편해 졌습니다.
basic_string
대부분 vector와 동일하며, string에 필요한 기능이 추가되었습니다.(basic_string의 멤버 함수들의 자세한 사용 방법은 레거시 C++ STL의 문자열을 참고하시기 바랍니다.)
정적 멤버 변수
항목 | 내용 |
---|---|
npos |
“찾을 수 없음”이나 “나머지 모든 문자”를 나타내는 의미로 사용합니다. |
1
static const size_type npos = -1;
생성자
항목 | 내용 |
---|---|
basic_string() |
빈 string 개체를 생성합니다. |
basic_string(const string& other) |
복사 생성합니다. |
basic_string(const value_type* ptr) |
C 언어 스타일의 문자열로부터 문자들을 복사하여 string 개체를 생성합니다. |
basic_string(const string& other, size_type, offset, size_type count = npos) basic_string(const value_type* ptr, size_type count) |
offset 위치 부터 count 갯수만큼 문자들을 복사하여 string개체를 생성합니다. |
basic_string(size_type count, value_type char_value) |
char_value 를 count 만큼 채운string을 생성합니다. |
basic_string(const_iterator first, const_iterator last) |
first 부터 last 직전까지의 요소(반개방 구조)를 복사하여 string 개체를 생성합니다. |
연산자
항목 | 내용 |
---|---|
operator =(const basic_stiring& other) |
other 를 복사 대입합니다. |
operator =(const basic_stiring&& other) noexcept (C++11~) |
other 를 이동 대입합니다. |
+ |
두 문자열을 연결하여 새로운 문자열을 만듭니다. |
+= |
문자열에 문자나 문자열을 추가합니다. |
== != (~C++20) |
두 문자열이 같은지, 다른지 검사합니다. 단순히 포인터 비교하는게 아니라 실제 문자들을 비교합니다. |
<, <=, >, >= (~C++20)<=> (C++20~) |
두 문자열을 대소 비교합니다. |
<<, >> |
출력 스트림에 출력하거나, 입력 스트림에서 문자열을 추출합니다. |
할당과 문자열 관리
항목 | string 특화 | 내용 |
---|---|---|
assign() | string의 기존 내용을 지우고 새로운 문자열을 복사합니다. | |
assign_range() (C++11~) |
(작성중) | |
get_allocator() (C++23~) |
(작성중) | |
resize() |
string의 새 크기를 지정하며, 필요에 따라 문자를 추가하거나 지웁니다. | |
size() length() |
O | string의 문자 갯수를 리턴합니다. string에서는 length 를 추가로 제공합니다. |
empty() | string이 비었는지 확인합니다. | |
capacity() | 메모리를 더 할당하지 않고 string에 저장할 수 있는 문자 갯수를 리턴합니다.(string은 vector와 동일하게 메모리 할당이 빈번히 발생하지 않도록 실제 문자 갯수보다 큰 크기를 할당하기도 하고, 삽입/삭제에 따라 실제 문자 갯수보다 더 많은 메모리를 관리할 수 있습니다.) | |
shrink_to_fit() |
(작성중) | |
reserve() | string의 메모리 공간을 최소한 count 갯수 만큼 문자를 저장할 수 있도록 예약합니다. |
|
max_size() |
string이 저장할 수 있는 최대 문자 갯수를 리턴합니다. | |
swap() |
두 string의 내부 데이터를 바꿔치기 합니다. |
문자 검색
항목 | string 특화 | 내용 |
---|---|---|
[] |
요소에 접근합니다. | |
at() | position 위치의 요소 참조자를 리턴합니다. position 이 잘못된 위치이면 [] 과 달리 예외가 발생하며, 검사 코드가 추가되어 상대적으로 속도 부하가 있습니다. |
|
begin(), end() |
순방향 이터레이터를 리턴합니다. | |
rbegin(), rend() |
역방향 이터레이터를 리턴합니다. | |
cbegin(), cend() |
순방향 이터레이터를 리턴합니다. 이때 요소를 수정할 수 없습니다. | |
crbegin() crend() |
역방향 이터레이터를 리턴합니다. 이때 요소를 수정할 수 없습니다. | |
data() | 컨테이너가 관리하는 메모리 블록을 리턴합니다. STL 구현에 따라 끝에 널문자(정수 0인 문자, '\0' )가 있을 수도 있지만, 표준이 아니기 때문에 널종료 문자열을 구할 때는 c_str()을 이용해야 합니다. |
|
c_str() | O | c 스타일의 널종료 문자열을 리턴합니다.(끝에 널문자(정수 0인 문자, '\0' )가 있습니다.) |
front() |
첫번째 요소의 참조자를 리턴합니다. string이 비었다면 아무 생각없이 실행되어 오동작 합니다. | |
back() |
마지막 요소의 참조자를 리턴합니다. string이 비었다면 아무 생각없이 실행되어 오동작 합니다. | |
find()rfind() |
O | 지정된 문자 시퀀스와 일치하는 첫번째 인덱스를 찾습니다. |
find_first_of()find_first_not_of() |
O | 지정된 문자들중 일치하는 문자가 있는 첫번째 인덱스를 찾습니다. |
find_last_of()find_last_not_of() |
O | 지정된 문자들중 일치하는 문자가 있는 마지막 인덱스를 찾습니다. |
operator basic_string_view() (C++17~) |
O | (작성중) |
요소 삽입/삭제/비교/추출
항목 | string 특화 | 내용 |
---|---|---|
clear() | 모든 요소를 지웁니다. 이때 메모리 영역은 그대로 입니다. | |
erase() | position 위치의 요소를 삭제하거나 first 와 last 직전까지의 요소(반개방 구조)를 삭제합니다. 이터레이터가 유효하지 않다면, 아무 생각없이 실행되어 오동작 합니다. |
|
erase_if() (C++20~) |
(작성중) | |
pop_back() |
마지막 요소를 삭제합니다. string이 비었다면 아무 동작 안합니다. | |
push_back() | string끝에 요소를 추가합니다. | |
insert() | position 으로 지정한 위치 앞에 삽입합니다. |
|
insert_range() (C++23~) |
(작성중) | |
append() | O | 문자열에 문자나 문자열을 추가합니다. |
append_range() (C++23~) |
(작성중) | |
compare() | O | 문자열을 대소 비교합니다. |
starts_with() (C++20~) | O | 주어진 부분 문자열로 시작하는지 검사합니다. |
ends_with() (C++20~) | O | 주어진 부분 문자열로 끝나는지 검사합니다. |
contains() (C++23~) |
O | (작성중) |
replace() | O | string의 요소를 지정한 문자나 다른 시퀀스로 바꿉니다. |
replace_with_range() (C++23~) |
O | (작성중) |
substr() | O | string에서 부분 문자열을 복사하여 리턴합니다. |
copy() | O | string에서 부분 문자열을 문자 배열에 복사합니다. |
getline() |
O | IO 스트림으로부터 데이터를 읽습니다. |
C스타일 문자열 함수
문자 분류
바이트 문자열 | 와이드 문자열 | 내용 |
---|---|---|
isalnum() |
iswalnum() |
(작성중) |
isalpha() |
iswalpha() |
(작성중) |
islower() |
iswlower() |
(작성중) |
islower() |
iswupper() |
(작성중) |
isupper() |
(작성중) | |
isdigit() |
iswdigit() |
(작성중) |
isxdigit() |
iswxdigit() |
(작성중) |
iscntrl() |
iswcntrl() |
(작성중) |
isgraph() |
iswgraph() |
(작성중) |
isspace() |
iswspace() |
(작성중) |
isblank() (C++11~) |
iswblank() (C++11~) |
(작성중) |
isprint() |
iswprint() |
(작성중) |
ispunct() |
iswpunct() |
(작성중) |
iswctype() |
(작성중) | |
wctype() |
(작성중) | |
locale() |
(작성중) |
문자 조작
바이트 문자열 | 와이드 문자열 | 내용 |
---|---|---|
tolower() |
towlower() |
(작성중) |
toupper() |
towupper() |
(작성중) |
towctrans() |
(작성중) | |
wctrans() |
(작성중) |
문자열 조작
바이트 문자열 | 와이드 문자열 | 내용 |
---|---|---|
strcpy() |
wcscpy() |
(작성중) |
strncpy() |
wcsncpy() |
(작성중) |
strcat() |
wcscat() |
(작성중) |
strncat() |
wcsncat() |
(작성중) |
strxfrm() |
wcsxfrm() |
(작성중) |
문자열 검사
바이트 문자열 | 와이드 문자열 | 내용 |
---|---|---|
strlen() |
wcslen() |
(작성중) |
strcmp() |
wcscmp() |
(작성중) |
strncmp() |
wcsncmp() |
(작성중) |
strcoll() |
wcscoll() |
(작성중) |
strchr() |
wcschr() |
(작성중) |
strrchr() |
wcsrchr() |
(작성중) |
strspn() |
wcsspn() |
(작성중) |
strcspn() |
wcscspn() |
(작성중) |
strpbrk() |
wcspbrk() |
(작성중) |
strstr() |
wcsstr() |
(작성중) |
strtok() |
wcstok() |
(작성중) |
메모리 조작
바이트 문자열 | 와이드 문자열 | 내용 |
---|---|---|
memchr() |
wmemchr() |
(작성중) |
memcmp() |
wmemcmp() |
(작성중) |
memset() |
wmemset() |
(작성중) |
memcpy() | wmemcpy() |
(작성중) |
memmove() |
wmemmove() |
(작성중) |
숫자 포맷
바이트 문자열 | 와이드 문자열 | 내용 |
---|---|---|
atof() |
(작성중) | |
atoi() atol() atoll() (C++11~) |
(작성중) | |
strtol() strtoll() (C++11~) |
wcstol() wcstoll() |
(작성중) |
strtoul() strtoull() (C++11~) |
wcstoul() wcstoull() |
(작성중) |
strtof() strtod() strtold() |
wcstof() wcstod() wcstold() |
(작성중) |
strtoimax() (C++11~)strtoumax() (C++11~) |
wcstoimax() (C++11~)wcstoumax() (C++11~) |
(작성중) |
와이드 문자열
타입
항목 | 내용 |
---|---|
wctrans_t |
(작성중) |
wctype_t |
(작성중) |
wint_t |
(작성중) |
매크로
항목 | 내용 |
---|---|
WEOF |
(작성중) |
WCHAR_MIN |
(작성중) |
WCHAR_MAX |
(작성중) |
멀티 바이트
다국어 처리는 와이드 문자열, UTF-16 인코딩 문자열, UTF-32 인코딩 문자열, UTF-8 인코딩 문자열을 사용하면 되므로 멀티 바이트를 사용할 일은 별로 없습니다. 비권고되기도 하고요. 이제 구버전 호환 용도 정도로만 사용하면 될 듯 하네요.(사용법은 멀티바이트 문자열을 참고하시기 바랍니다.)
멀티 바이트 문자열과 와이드 문자열간 변환
항목 | 내용 |
---|---|
mblen(str) | str 주소의 멀티 바이트 문자가 몇 바이트 크기인지 구합니다. |
mbtowc() |
멀티 바이트 문자를 와이드 문자로 변환합니다. |
wctomb() |
와이드 문자를 멀티 바이트 문자로 변환합니다. |
mbstowcs() | 멀티 바이트 문자열를 와이드 문자열로 변환합니다. |
wcstombs() |
와이드 문자열을 멀티 바이트 문자열로 변환합니다. |
mbsinit() |
(작성중) |
btowc() |
(작성중) |
wctob() |
(작성중) |
mbrlen() |
멀티 바이트 문자가 몇 바이트 크기인지 구합니다. 이때 mbstate_t 를 이용하여, 멀티 바이트 문자의 변환 상태를 저장하고 사용합니다. |
mbrtowc() |
mbtowc() 와 같습니다. 이때 mbstate_t 를 이용하여, 멀티 바이트 문자의 변환 상태를 저장하고 사용합니다. |
wcrtomb() |
wctomb() 와 같습니다. 이때 mbstate_t 를 이용하여, 멀티 바이트 문자의 변환 상태를 저장하고 사용합니다. |
mbsrtowcs() |
mbstowcs()와 같습니다. 이때 mbstate_t 를 이용하여, 멀티 바이트 문자의 변환 상태를 저장하고 사용합니다. |
wcsrtombs() |
wcstombs() 와 같습니다. 이때 mbstate_t 를 이용하여, 멀티 바이트 문자의 변환 상태를 저장하고 사용합니다. |
mbrtoc16() (C++11~) |
멀티 바이트 문자를 UTF-16 인코딩 문자로 변환합니다. 이때 mbstate_t 를 이용하여, 멀티 바이트 문자의 변환 상태를 저장하고 사용합니다. |
c16rtomb() (C++11~) |
UTF-16 인코딩 문자를 멀티 바이트 문자로 변환합니다. 이때 mbstate_t 를 이용하여, 멀티 바이트 문자의 변환 상태를 저장하고 사용합니다. |
mbrtoc32() (C++11~) |
멀티 바이트 문자를 UTF-32 인코딩 문자로 변환합니다. 이때 mbstate_t 를 이용하여, 멀티 바이트 문자의 변환 상태를 저장하고 사용합니다. |
c32rtomb() (C++11~) |
UTF-32 인코딩 문자를 멀티 바이트 문자로 변환합니다. 이때 mbstate_t 를 이용하여, 멀티 바이트 문자의 변환 상태를 저장하고 사용합니다. |
mbrtoc8() (C++20~) |
멀티 바이트 문자를 UTF-8 인코딩 문자로 변환합니다. 이때 mbstate_t 를 이용하여, 멀티 바이트 문자의 변환 상태를 저장하고 사용합니다. |
c8rtomb() (C++20~) |
UTF-8 인코딩 문자를 멀티 바이트 문자로 변환합니다. 이때 mbstate_t 를 이용하여, 멀티 바이트 문자의 변환 상태를 저장하고 사용합니다. |
타입
항목 | 내용 |
---|---|
mbstate_t |
(작성중) |
매크로
항목 | 내용 |
---|---|
MB_LEN_MAX |
(작성중) |
MB_CUR_MAX | 현재 locale()에서 멀티 바이트 문자의 최대 크기입니다. |
__STDC_UTF_16__ (C++11~) |
(작성중) |
__STDC_UTF_32__ (C++11~) |
(작성중) |
strerror()
errorno를 문자열로 출력해 줍니다.
(C++11~) 숫자 변환
항목 | 내용 |
---|---|
stoi(), stol(), stoll() (C++11~) |
부호 있는 정수를 문자열로 바꿉니다. |
stoul(), stoull() (C++11~) |
부호 없는 정수를 문자열로 바꿉니다. |
stof(), stod(), stold() (C++11~) |
실수를 문자열로 바꿉니다. |
to_string() (C++11~) |
string을 정수 또는 실수로 바꿉니다. |
to_wstring() (C++11~) |
wstring을 정수 또는 실수로 바꿉니다. |
(C++17~) 숫자/문자열 변환
C++17 부터 숫자와 문자열간의 변환을 위한 to_chars(), from_chars() 함수가 제공되며, 기존 C스타일(atoi(), strtol()등) 보다 안전합니다.
항목 | 내용 |
---|---|
to_chars() (C++17~) | 정수, 실수를 문자열로 변환합니다. |
to_chars_result (C++17~) |
to_chars() 의 리턴값입니다. 변환된 문자열을 끝 포인터(ptr )와 에러 코드(ec , errc 타입)로 구성됩니다. |
from_chars() (C++17~) | 문자열을 정수, 실수로 변환합니다. |
from_chars_result (C++17~) |
from_chars() 의 리턴값입니다. 인자로 전달된 문자열에서 숫자로 해석할 수 없는 위치(ptr )와 에러 코드(ec , errc 타입)로 구성됩니다. |
chars_format (C++17~) |
scientific, fixed, hex, general(fixed 와 scientific) 옵션을 제공합니다. |
to_char()와 from_char()는 데이터와 에러 코드를 함께 리턴하는데요, 구조화된 바인딩을 사용하면 좀더 간결하게 코딩할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
char buf[10];
{
// 11을 10진수 문자열로 변환
auto [ptr, ec]{std::to_chars(buf, buf + sizeof(buf), 11, 10)}; // 구조화된 바인딩. std::to_chars_result result{std::to_chars()} 와 동일
if (ec == std::errc{}) {
EXPECT_TRUE(std::string(buf, ptr - buf) == "11");
}
}
{
// 11을 16진수 문자열로 변환
auto [ptr, ec]{std::to_chars(buf, buf + sizeof(buf), 11, 16)};
EXPECT_TRUE(std::string(buf, ptr - buf) == "b");
}
{
char str[]{"11year"}; // 숫자와 일반 문자로 구성됩니다.
int result{0};
auto [ptr, ec]{std::from_chars(str, str + sizeof(str), result)};
if (ec == std::errc{}) {
EXPECT_TRUE(result == 11); // 숫자 부분만 잘 변환합니다.
}
EXPECT_TRUE(ptr == &str[2]); // ptr은 숫자 다음 위치입니다. 즉, 'y' 위치입니다.
}
댓글남기기