프로그래밍/C++

C++ string 사용법 및 기능정리(동작방식)

Hwan2 2019. 11. 25. 21:13
반응형

 

 

 

C++에는 string이란 클래스가 있습니다.

이걸 사용하려면 string 헤더파일을 선언해 줘야 하며 다양한 기능을 제공합니다.

 

그렇다면 string이란 녀석이 왜 생겨났을까??

 

기존 C언어에서 문자열 처리를 하려면 상당히 골치 아팠습니다. 특히 가변 길이를 처리할때요.

 

프로그래머가 손수 메모리를 재 할당 해주거나 그게 아니라면 충분한 문자열 배열을 선언해주거나...

 

너무 번거롭고 나중에 문제생길 것들이 많았죠... 예상치 못한 결과도 초래했다고 합니다.

 

그래서 C++에서는 class로 문자열을 감싸고 public을 통해 쉽게 사용할 수 있도록 정의하고 만들었습니다.

 

그래서 C++은 문자열 사용을 기본적으로 string으로 하고 있습니다.

 

 

그렇다면 string에 사용법에 대해 알아보도록 하겠습니다.

 

 

 

 

 

 

 

String 초기화

 string s   s 라는 string변수 선언 
 string s("Hwan")   s 변수를 "Hwan"이라는 값으로 초기화 
 string s = "Hwan"   s 변수를 "Hwan"이라는 값으로 초기화
 string s.assign()   string s("Hwan") 과 동일한 기능

 

/////////////////////////////////////////////////////////
string s;        //변수 선언
/////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////
string s = "Hwan";        //output : Hwan
/////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////
string s1("Hwan");        //output : Hwan
string s2(4, 'A');        //output : AAAA
string s3(s1, 0, s1.length() - 2);    //output : HW
string s4(s1, 2, s1.length());        //output : an
string s5(s2);            //output : AAAA
string s6("ABCDE", 3);        //output : ABC

char c[] = "TEST Code!!";
string s7(c);        //output : TEST Code!!
/////////////////////////////////////////////////////////​

 

 

String Element access(String 요소 접근)

 s.at(숫자)  string 문자열의 i번째 참조(범위검사 함)
 s.[숫자]  string 문자열의 i번째 참조(범위검사 안함)
 s.front()  string 문자열의 첫번째 요소 반환(char type)
 s.back()  string 문자열의 마지막 요소 반환(char type) 
 s.c_str()   string 문자열을 const char* 로 접근할 수 있도록 해줌('\0' 문자 포함) 

 

string s = "ABCDE123";

cout << s.at(2) << endl;     //output : C (범위가 맞지 않으면 예외처리를 함)
cout << s[0] << endl;         //output : A
cout << s.front() << endl;    //output : A
cout << s.back() << endl;    //output : 3

const char * c = s.c_str();    //배열로써 접근이 가능하며 '\0'에 접근이 가능하다.

cout << c << endl;            //output : ABCDE123

cout << (c_arr == s) ? true : false;    //output : 1(true)
cout << (&(c_arr[0]) == &(s[0])) ? true : false;    //output : 1(true)​

 

 

 

string에서의 at[]의 차이점은 범위검사를 통한 예외처리입니다. 백터와 같은데 at은 범위검사를 하고 해당 범위 이외의 값이 들어오면

std::out_of_range를 발생시킵니다.

 

반면 []는 범위검사를 하지 않으며, 예외처리가 아닌 VC++ or g++의 디버깅이 일어나게 됩니다.

 

 

 

 

 

 

 

String Iterator

 s.begin()  string의 시작 주소 반환 
 s.end()  string의 (마지막 + 1) 주소 반환 
 s.rbegin()  string의 마지막 주소를 반환 
 s.rend()  string의 (첫번 째 - 1 ) 주소 반환 

 

 

string s = "ABCDE123";
string::iterator iter = s.begin();
string r_s, cp;

for (; iter != s.end(); iter++) {
        cout << *iter;
        if (*iter == 'E')
            break;
}        //output : ABCDE


copy(s.rbegin(), s.rend(), back_inserter(r_s));
copy(s.begin(), s.end(), back_inserter(cp));
    
cout << r_s << endl;    //output : 321EDCBA
cout << (s == r_s) ? true : false;    //output : 0(false)
cout << (s == cp) ? true : false;    //output : 1(true)
cout << (&(s[0]) == &(cp[0])) ? true : false;    //output : 0(false)​
 

 

 

String의 iterator에 대한 사진입니다.

출처 : https://en.cppreference.com/w/cpp/string/basic_string/rbegin

 

 

 

 

 

 

 

 

 

String Capacity (용량 확인)

 s.empty()   string이 비어있으면 true, 아니면 false 반환
 s.size(), s.length()  string에 들어있는 요소에 대한 길이 반환 
 s.capacity()   string에 할당된 실제 크기 반환 
 s.max_size()   string에 할당될 수 있는 최대 메모리 크기 반환 
 s.reserve(숫자)  해당 숫자만큼 capactiy 길이를 설정 
 s.shrink_to_fit()   잉여 capacity 공간을 조절해 준다. 

 

string s = "ABCDE123";

cout << s.length() << endl;        //output : 8
cout << s.size() << endl;        //output : 8
cout << s.capacity() << endl;    //output : 15

s.reserve(100);
cout << s.size() << endl;        //output : 8
cout << s.capacity() << endl;    //output : 111

s.shrink_to_fit();
cout << s.capacity() << endl;    //output : 15​

 

 

 

string은 기본적으로 capacity의 크기를 15로 맞춰주고 있습니다. 

또한 reserve를 통해 capacity의 크기를 늘려도 100이 아닌 111인걸 볼 수 있습니다.

string은 이렇듯 설정한 크기보다 좀 더 여유있는 메모리 공간을 갖게 됩니다.

이는 vector의 메모리 할당부분과 다릅니다.

 

 

 

 

 

 

 

 

 

 

 

String Operations (String의 기능)

 s.clear()  s에 있는 값들을 지워준다. (size = 0)
 s.insert()  s에 사용자가 원하는 위치에 문자 삽입 가능
 s.erase()  s문자열 중 사용자가 원하는 부분 삭제
 s.push_back()   s문자열 뒤에 단어 추가. (문자열 X, 문자 O)
 s.pop_back()   s문자열 맨 뒤 단어 하나 삭제. (s.size() - 1) 
 s.operator +=   문자열 뒤에 문자열 추가 가능
 s.append()  문자열 뒤에 문자열 추가 가능
 s.compare()   문자열 비교 함수 
 s.replace()   문자열 수정
 s.substr()   문자열 중 원하는 부분을 잘라서 넘겨준다. 
 s.copy()   s문자열을 (char [])형식의 배열 변수에 복사
 s.resize()   s문자열 길이를 수정
 s.swap()   s문자열과 다른 문자열을 서로 바꿈 
 s.starts_with(문자열)   s문자열에 대해 입력한 문자열이 시작 위치부터 동일한지 여부
 s.ends_with(문자열)   s문자열에 대해 입력한 문자열이 끝 위치부터 동일한지 여부

 

 

string s = "ABCDE123"

s.insert(0, "TEST");    //output : TESTABCDE123
s.insert(s.begin() + s.find_first_of('D') + 1, ':'); // output : TESTABCD:123(문자만 가능)


////////// (compare) s = TESTABCD:123  /////////////
s.compare("TESTABCD:123");                //output : 0
s.compare("a");                            //output : -1
s.compare("X");                            //output : -1
s.compare("BBBBBBBBBBBBBBB");             //output : 1
s.compare("100000000000000000000000");    //output : 1
s.compare("VVVVV");                        //output : -1


////////// (erase) s = TESTABCD:123  /////////////
s.erase(0, 4);        //output : ABCD:123
s.erase(find(s.begin(), s.end(), 'D'));        //output : ABC:123('D'만 지움)
s.erase(s.find(':'));        //output : ABC(':'부터 뒤 문자까지 모두 지움)


////////// (push, pop) s = ABC  /////////////
s.push_back('S');    //output : ABCS
s.pop_back();        //output : ABC


////////// (append) s = ABC  /////////////
s.append("TEST");    //output : ABCTEST
s.append(1, '1');    //output : ABCTEST1
s.append("123456789", 3, 3);    //output : ABCTEST1456


////////// (clear) s = ABCTEST1456  /////////////
const char c[] = "Hwan";
s.append(c);        //output : ABCTEST1456Hwan
s += c;        //output : ABCTEST1456HwanHwan(capacity() = 15 -> 31)
s.clear();    //s.size() = 0, s.capacity() = 31


////////// (replace) s = ''  /////////////
s.append("ABCD123");        //output : ABCD123
s.replace(4, 2, "Hwan");    //output : ABCDHwan3
s.replace(s.find('H'), s.size() - s.find('H'), "WOW");    //output : ABCDWOW


////////// (substr) s = ABCDWOW  /////////////
string temp = s.substr(4);        //output : WOW;
temp = s.substr(3, 2);            //output : DW;
temp = s.substr(s.size() - 3, 50);    //output : WOW;


////////// (copy) s = ABCDWOW  /////////////
char arr[5]{};
s.copy(arr, sizeof arr - 1);    //output : ABCD (마지막 '\n' 포함)


////////// (resize) s = ABCDWOW  /////////////
s.resize(100);    //output : ABCDWOW, s.size() = 100, s.capacity() = 111
s.resize(4);    //output : ABCD, s.size() = 4, s.capacity() = 15


////////// (swap) s = ABCD  /////////////
string sw = "AAA";
s.swap(sw);        //s = "AAA", sw = "ABCD"


/////////// c++ 20 ///////////////////
s = "hello Hwan";
s.starts_with("hello");    //output : true;
s.starts_with('h');        //output : true;
s.starts_with("Hwan");    //output : false;
s.starts_with('x');        //output : false;

s.ends_with("Hwan");        //output : true;
s.ends_with('n');        //output : true;
s.ends_with("hello");    //output : false;
s.ends_with('q');        //output : false;​

 

 

compare의 경우 문자가 같으면 0을 반환합니다.

반대로 다를경우 1 or -1 을 반환하는데 조건은 다음과 같습니다.

문자열 기준 '숫자 < 대문자 < 소문자' 순으로 크기를 비교합니다.

그래서 비교 문자중 자신이 더 크면 1을 반환, 작으면 -1을 반환합니다.

 

 

string 같은경우 삽입하거나 지울 때 하나씩 일일이 옮기는 작업을 하게 됩니다. 즉 O(n)입니다.

또한 삽입중 capacity()값보다 크게 증가될 경우 reallocate이 발생하게 됩니다.

따라서 삽입과 삭제는 되도록 하지 않는것이 좋습니다.

 

 

 

 

 

String Search (문자 찾기)

 find(문자 or 문자열)  찾은 index값을 정수형태로 넘겨준다. 못찾으면 -1을 반환  
 rfind(문자 or 문자열)   find와 동일하지만 뒤에서부터 찾는다. 
 find_first_of(문자 or 문자열)  문자 or 문자열 중 첫 index부터 검색해서 하나라도 맞으면 
 해당 index 값을 반환. 못찾으면 쓰레기값 반환(npos)
 find_first_not_of(문자 or 문자열)  문자 or 문자열 중 첫 index부터 검색해서 없는 값을 찾아내 
 해당 index를 반환. 모두 포함되 있다면 -1 반환
 find_last_of(문자 or 문자열)  문자 or 문자열 중 마지막 index부터 검색해서 하나라도 맞으면
 해당 index 값을 반환. 못찾으면 쓰레기값 반환(npos)
 find_last_not_of(문자 or 문자열)  문자 or 문자열 중 마지막 index부터 검색해서 없는 
 값을 찾아내 해당 index를 반환. 모두 포함되 있다면 -1 반환

 

string s = "ABCD 123 abc";

s.find('C');        //output : 2
s.find("CD");        //output : 2
s.find("CDEF");        //output : npos
s.find(' ', 6);        //output : 8

s.rfind(' ');        //output : 8

s.find_first_of('1');    //output : 5
s.find_first_of(' ');    //output : 4
s.find_first_of('x');    //output : npos

s.find_last_of('3');    //output : 7
s.find_last_of(' ');    //output : 8

s.find_first_not_of("ABCDEFG1234567abcdef");    //output : 4
s.find_first_not_of("ABCDEFG1234567abcdef ");    //output : -1

s.find_last_not_of("ABCDEFG1234567abcdef");        //output : 8
s.find_last_not_of("ABCDEFG1234567abcdef ");    //output : -1​
 
 
 

 

 

반응형