std::string class?

- c++에서는 문자열을 다루기 위해 std::string class를 사용할 수 있다.
- <string> header를 include 해준 뒤에, string class를 사용할 수 있다.
- 코딩테스트에서 문자열을 처리하는 문제가 빈번하게 나오니, 미리 사용법을 알아두면 좋을 것 같다.


std::string 사용법

- C++ code에서 string를 사용하기 위해서는 <string> header를 include해주어야 한다.

#include <string>

* 선언 (Declaration)

- 기본적인 string 선언법

#include <string>

using namespace std;

string s("Hello World!");
string s1 = "Hello World!";
string s2(s1);

 

* 사용법

1. string에서의 위치 지칭 및 string의 크기 구하기
  - N 크기의 길이를 가지는 string의 indexing은 0부터 N-1 까지 가능하다.
  - string class는 c언어의 char*(char배열)과는 달리 '\0'가 마지막에 삽입되지 않아도 된다.
  (예를 들어, 5크기의 길이를 가지는 string은 0~4까지의 index에 접근할 수 있다.)

string s = "ABCDE";

int s_len = s.size();    // size of string (5)
int s_len2 = s.length(); // size of string (5)

string::iterator begin_it = s.begin();  // first element를 가르키는 iterator
string::iterator end_it = s.end();      // end element를 가르키는 iterator

char front_val = s.front();  // front_val: 'A'
char back_val = s.back();    // back_val: 'E'

char first_val  = s[0];      // first_val: 'A'
char first_val2 = s.at(0);   // first_val2: 'A'
char second_val  = s[1];     // second_val: 'B'
char second_val2 = s.at(1);  // second_val2: 'B'
char last_val  = s[4];           // last_val: 'E'
char last_val2 = s[s_len-1];     // last_val2: 'E'
char last_val3 = s.at(4);        // last_val3: 'E'
char last_val4 = s.at(s_len-1);  // last_val4: 'E'

 

2. string에서의 값 추가 및 삭제, 복사, 검색
  - find()는 앞에서부터, rfind()는 뒤에서부터 검색 문자(열)을 찾아, 해당 index를 반환해준다.
  (못 찾았을 경우에, 'std::npos' 라는 쓰레기값을 반환해준다.)

- vector에서와 같이, string에서도 push_back()과 pop_back()이 가능하다.
- string은 원하는 곳에 문자(열)을 삽입하거나 삭제할 수 있지만, 시간복잡도가 O(n)이 소요된다.
- string에서 맨 뒤에 문자(열)을 삽입하는 것은 append()나 '+' operation을 사용하면 된다.
- clear() 함수를 사용하면 해당 string 변수를 size가 0인 string으로 초기화 할 수 있다.

string s = "ABCDE";

int B_idx = s.find('B');   // B_index: 1
int D_idx = s.rfind('DE'); // D_index: 3

s.insert(0, "123");   // s: "123ABCDE"
s.append("456");      // s: "123ABCDE456"
s = s + "FGH";        // s: "123ABCDE456FGH"

s.erase(0, 3);        // s: "ABCDE456FGH" (0~2[=3-1] index 값을 삭제)
s.erase(s.find('4')); // s: "ABCDE" (index 0부터 검색하여 최초의 '4' 위치 이후의 값을 다 삭제)

s.clear();            // Initialize string variable 's' 
s.push_back('F');     // s: "F"
s.push_back('G');     // s: "FG"
s.pop_back();         // s: "F"

 

3. string class에서의 유용한 기능들 (비교, substring, char*로의 변환)
  - 문자열을 비교하는 compare()는 같을 때 0, 다를 경우 -1 혹은 1을 반환한다.
    ([숫자 < 영어대문자 < 영어소문자] 순으로 비교를 진행하여 자신이 더 크면 1, 작으면 -1을 반환한다.)

  - 'substr()'의 경우, 한개의 parameter만 입력 시 문자열의 끝부분까지 잘라서 반환한다.
    (만약 2개의 parameter를 입력한다면, 그 길이만큼만 잘라서 반환한다.)

  - 'c_str()'을 이용하여 c++ class인 string에서 c type의 char* 로의 변환이 가능하다.

string s = "ABCDE";

int c_val;
c_val = s.compare("ABCDE"); // c_val: 0
c_val = s.compare("abcde"); // c_val: -1
c_val = s.compare("12345"); // c_val: 1

string sub_str1 = s.substr(2);       // sub_str1: "CDE"
string sub_str2 = s.substr(1, 3);    // sub_str2: "BCD"
string sub_str3 = s.substr(2, 5000); // sub_str3: "CDE"

const char* ctype_c = s.c_str(); // ctype_c: "ABCDE"

 

4. string을 특정 delimiter을 통해 parsing(tokenizing)하기
(1) istringstream class (delimiter가 1개일 때)
  - string을 parsing(tokenizing)하는 방법 중 하나로 istringstream class을 사용할 수 있다.
  - stringstream class는 <sstream>을 include 한 뒤에 사용할 수 있다.

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int main()
{
	string line = "first second third fourth";
	stringstream sstream(line);
	string token;

	while (getline(sstream, token, ' '))
	  cout << token << endl;
	/* output:
	first
	second
	third
	fourth
	*/
	return 0;
}

 

(2) find와 substr을 이용하는 방법 (delimiter가 2개 이상일 때)
- string을 parsing(tokenizing)하는 방법 중 하나로 istringstream class을 사용할 수 있다.
- stringstream class는 <sstream>을 include 한 뒤에 사용할 수 있다.

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
	string s = "apple,pear,peach,melon";
	vector<string> v;

	int prev_idx = 0;
	int cur_idx = s.find(",");

	while (cur_idx != string::npos) {
		string sub_s = s.substr(prev_idx, cur_idx - prev_idx);
		v.push_back(sub_s);
		prev_idx = cur_idx + 1;
		cur_idx = s.find(',', prev_idx);
	}

	v.push_back(s.substr(prev_idx, cur_idx - prev_idx));

	for (int i=0; i<v.size(); i++) 
		cout << v[i] << endl;
	/* output:
    apple
    pear
    peach
    melon
    */
	
	return 0;
}
 
 

(3) 정규 표현식(Regular Expression)을 사용하는 방법
- 정규표현식을 잘 아는 사람이라면, 아래 링크에 첨부된 방법들을 사용하면 좋을 것 같다.
(https://plein-de-verite.tistory.com/339)


*참고자료
1. https://blockdmask.tistory.com/338
2. https://chbuljumeok1997.tistory.com/42