C++/C++ 기초

[C++] String 클래스 / 메소드

Song 컴퓨터공학 2023. 5. 4. 15:19

문자열(string) 이란 메모리에 저장된 일련의 연속된 문자들의 집합을 의미합니다. C++ 에서는 2가지 방법으로 문자열을 생성할 수 있습니다.

 

1. C와 동일한 방식 (배열)

2. string 클래스를 이용한 문자열

 

먼저 C와 동일한 방식으로 문자열을 간단히 만들어보고, 왜 string 클래스를 써야 하는가에 대해 알아봅시다.

 

C와 동일한 방법으로 C++에서는 문자열을 입력받기 위해 문자열이 저장될 문자형 배열을 미리 선언해야 합니다.

#include <iostream>
using namespace std; // std라는 name space에 속한 정의들은 이름 안붙이고 사용 가능


int main()
{
	const int SIZE = 10;

	char name[SIZE];
	char address[SIZE];

	cout << "이름 : ";
	cin >> name;
	cout << "주소 : ";
	cin >> address;

	cout << name << "의 주소 :" << address;
	return 0;
}

 

위 예제는 2개의 문제점을 가지고 있습니다.

 

1. 이름에 띄어쓰기가 들어가면 주소를 입력할 수 없다.

2. 10바이트 이상의 이름이나 주소를 입력하면 프로그램이 강제 종료된다.

 

C++ 에서 cin 객체는 띄어쓰기를 포함한 탭 문자, 캐리지 리턴 문자 등을 모두 문자열의 끝으로 인식합니다. 따라서 띄어쓰기를 포함한 문자열을 모두 입력 받으려면 cin 객체의 get() 메소드를 사용하여 수정해야 합니다.

 

#include <iostream>
using namespace std; // std라는 name space에 속한 정의들은 이름 안붙이고 사용 가능


int main()
{
	const int SIZE = 10;

	char name[SIZE];
	char address[SIZE];

	cout << "이름 : ";
	cin.get(name, SIZE).get();
	cout << "주소 : ";
	cin.get(address, SIZE).get();

	cout << name << "의 주소 :" << address;
	return 0;
}

 

2가지 문제 중에서 첫 번째 문제, 띄어쓰기를 포함한 입력을 받지 못하는 문제는 cin 객체의 get 메소드를 통해 해결했습니다. 그러나 아직 10 바이트 이상의 데이터는 입력 받으면 프로그램이 강제 종료되는 상황입니다. 이는 cin 객체의 ignore() 메소드를 통해 해결 가능합니다.

 

#include <iostream>
using namespace std; // std라는 name space에 속한 정의들은 이름 안붙이고 사용 가능


int main()
{
	const int SIZE = 10;

	char name[SIZE];
	char address[SIZE];

	cout << "이름 : ";
	cin.get(name, SIZE).ignore(SIZE, '\n');
	cout << "주소 : ";
	cin.get(address, SIZE).ignore(SIZE, '\n');

	cout << name << "의 주소 :" << address;
	return 0;
}

ignore 메소드를 사용하면, SIZE 를 넘는 데이터를 입력해도 정확히 10 바이트까지만 입력을 받아서 저장합니다. 그러면 이제는 정상적으로 실행은 잘 되는 것이죠. 그런데 내가 굳이 입력할 문자열의 길이를 알지 못하는 상황에서도 문자를 받는 방법은 없을까요? 기존의 C 언어 방식의 문자열 입력에서는 입력할 문자열의 길이를 알고 있어야만 합니다. 이 문제는 C++ 에서 제공하는 string 클래스를 이용하면 아주 간단하게 해결할 수 있습니다.

#include <iostream>
#include <string>
using namespace std; // std라는 name space에 속한 정의들은 이름 안붙이고 사용 가능


int main()
{
	string address, name;

	cout << "이름 : ";
	getline(cin, name);
	cout << "주소 : ";
	getline(cin, address);

	cout << name << "의 주소 : " << address;
	return 0;
}

위처럼 string 클래스를 사용하면 문자열의 띄어쓰기 문제나 문자열의 길이에 상관없이 모든 문자열을 정확히 입력받을 수 있습니다. getline 함수는 아래의 문자열 처리에서 다뤄보도록 하겠습니다.

 


 

String 클래스

 

String 클래스는 문자형 배열보다 사용하기 편리하며, 문자열을 하나의 타입처럼 표현할 수 있게 해 줍니다. C++ 에서 string 클래스를 사용하기 위해서는 string 헤더파일을 포함해야 합니다. 또한 string 클래스는 std 네임스페이스에 속해 있으므로, using 지시자를 사용하거나 해당 네임스페이스를 참조해서 사용해야 합니다.

 

string str1;          // 문자열 선언
str1 = "Song Blog";   // 문자열 초기화
string str2 = "C++";  // 문자열 선언과 동시에 초기화

 

string 객체는 위처럼 문자열을 배열 형태가 아닌 단순한 변수로 선언해 사용합니다. 따라서 사용자가 길이를 명시하지 않아도 되고, 문자열의 길이에 대한 문제는 C++ 프로그램이 자동으로 처리해 줍니다. 위처럼 먼저 str1 을 선언하기만 하면 길이가 0인 string 객체가 생성됩니다. 그 이후에 문자열을 초기화하면 C++ 프로그램이 str1 의 길이를 자동으로 조절해 주는 방식으로 동작합니다.

 

#include <iostream>
#include <string>
using namespace std; // std라는 name space에 속한 정의들은 이름 안붙이고 사용 가능

int main()
{
	string a;

	a = "abcdefg";
	cout << "문자열의 3번째 글자는 " << a[2];
	cout << "\n문자열의 길이는 " << a.length() <<"이다.";
	return 0;
}

string 객체로 만든 문자열도 배열처럼 인덱스를 통해 다룰 수 있습니다. 또한 length() 메소드를 통해 길이를 알수도 있죠.

 


문자열 처리

 

String 객체를 이용한 문자열의 처리는 문자형 배열을 이용하는 방식보다 훨씬 간단합니다. 이전의 C에서 문자형 배열 사이의 대입은 strcpy() 나 strncpy() 함수를 사용해야 했죠. string 객체를 이용한 문자열에서는 대입 연산자 만을 사용하여 대입 작업을 할 수 있습니다.

 

또한 문자형 배열 사이의 추가나 결합은 strcat() 함수나 strncat() 함수를 사용했죠. string 객체를 사용하면 복합 대입 연산자(+=) 나 append() 메소드를 이용해 손쉽게 추가나 결합을 할 수 있습니다.

 

#include <iostream>
#include <string>
using namespace std; // std라는 name space에 속한 정의들은 이름 안붙이고 사용 가능

int main()
{
	string str1 = "Song Tistory Blog", str2, str3 = " Best", str4;
	str2 = str1;        // 문자열 대입 연산
	cout << str2 << endl;
	str4 = str2 + str3; // 문자열 결합 연산 : Song Tistory Blog + Best
	cout << str4 << endl;
	str2 += str3;       // 문자열 추가 연산
	cout << str2;
}

 

 


 

문자열 입출력

string 객체를 이용한 문자열의 입력에는 cin 객체를, 출력에는 cout 객체를 사용할 수 있습니다. 하지만 cin 객체를 이용한 문자열의 입력은 한 단어 단위로 수행되기 때문에 문자열을 한 행(line)씩 읽고 싶을 때는 getline() 함수를 사용해야 합니다. 아까 위의 예제코드에서도 getline 함수를 써봤기 때문에 예시 코드는 생략합니다. getline() 함수는 첫 번째 매개변수로 cin 객체를, 두 번째 매개변수로 문자열을 저장할 string 객체 변수를 전달받습니다.

 

 


 

String 메소드

 

String 메소드는 String 클래스에 정의된 문자열 관련 작업을 할 때 사용하는 메소드 입니다.

 

대표적으로 오늘 포스팅에서 알아볼 메소드는 아래와 같습니다.

 

1. length() 메소드, size() 메소드

2. append() 메소드

3. find() 메소드

4. compare() 메소드

5. replace() 메소드

 


length() 메소드, size() 메소드

위에서도 한 번 사용해 봤지만, 문자열의 길이를 반환하는 메소드입니다. size() 메소드도 length() 메소드와 항상 같은 값을 반환하지만 의미가 살짝 다릅니다. length() 메소드는 문자열의 길이size() 메소드는 해당 string 객체가 메모리에서 사용하고 있는 실제 크기 를 나타냅니다.

 

append() 메소드

append() 메소드의 원형은 아래와 같습니다.

문자열.append(추가문자열)					// 추가 문자열을 맨 끝에 추가
문자열.append(추가문자열, 시작위치, 개수)	  // 추가 문자열의 시작 위치부터 개수만큼만 끝에 추가
문자열.append(개수, 추가할문자) 			  // 추가할 문자를 개수만큼 맨 끝에 추가

이건 간단한 예시 코드를 보면서 이해해보겠습니다.

#include <iostream>
#include <string>
using namespace std; // std라는 name space에 속한 정의들은 이름 안붙이고 사용 가능

int main()
{
	string str1, str2, str3;

	str1.append("Song Tistory Blog");
	str2.append("Song Tistory Blog", 5, 7);
	str3.append(3, 'T');
	cout << str1 << endl;
	cout << str2 << endl;
	cout << str3;
}

 

find() 메소드

find() 메소드는 특정 문자열을 찾아, 그 시작 위치를 반환하는 메소드입니다.

문자열.find(찾을문자열);			// 인덱스 0부터 찾을 문자열을 찾아 시작 위치 반환
문자열.find(찾을문자);				 // 인덱스 0부터 찾을 문자를 찾아 시작 위치 반환
문자열.find(찾을문자열, 시작위치);  // 시작 위치부터 찾을 문자열을 찾아 시작 위치 반환

find() 메소드는 해당 문자열에서 찾을 문자열을 찾지 못하면, string::size_type 의 string::npos 라는 상수를 반환합니다. 정적 상수인 string::npos 는 string 클래스에 static const size_type = -1 로 명시되어 있습니다.

#include <iostream>
#include <string>
using namespace std; // std라는 name space에 속한 정의들은 이름 안붙이고 사용 가능


int main()
{
	string str = "Song Tistory Blog";
	
	cout << str.find("Blog") << endl;
	cout << str.find('i') << endl;

	if (str.find("Song", 5) != string::npos)
	{
		cout << "해당 문자열을 찾았습니다.";
	}
	else
	{
		cout << "해당 문자열을 찾지 못했습니다.";
	}
}

 

compare() 메소드

이름부터 비교할 것 같은 compare() 메소드는 두 문자열 간의 내용을 비교하는 메소드입니다.

str1.compare(str2) == 0 // str1 과 str2 가 같은 경우
str1.compare(str2) < 0  // str1이 str2 보다 사전 편찬순으로 앞에 있을 경우 (str1이 더 작은 경우)
str1.compare(str2) > 0  // str1이 str2 보다 사전 편찬순으로 뒤에 있을 경우 (str1이 더 큰 경우)

C 언어의 strcmp() 함수와 동일합니다.

 

 

replace() 메소드

replace() 메소드는 특정 문자열을 찾아, 그 문자열을 다른 문자열로 대체 하는 메소드입니다.

문자열.replace(대체할문자열의시작위치, 대체할문자열의길이, 새로운문자열);
// 전달된 시작 위치부터 문자열의 길이만큼을 제거한 후에, 새로운 문자열을 삽입함

아래 예제는 "Computer" 라는 문자열을 찾아, "Electronic" 으로 바꾸는 코드입니다.

#include <iostream>
#include <string>
using namespace std; // std라는 name space에 속한 정의들은 이름 안붙이고 사용 가능


int main()
{
	string str = "Song Computer";
	
	cout << str.replace(str.find("C"), size("Electronics"), "Electronics");
}

 

길고 긴 String 클래스와 메소드 정리가 끝났습니다. 그래도 C를 먼저 배우신 분이라면 이게 얼마나 간편한 기능인지 몸소 느낄 수 있을 것 같습니다. 그만큼 유용하고 편리한 기능이니 C++ 을 다룰 때 필수적으로 알아야 하는 부분입니다. 감사합니다.