문자열을 다루기 위한 매우 중요한 자료형이다
동적으로 메모리를 할당하여 크기를 조정하기 때문에 문자열의 길이에 상관이 없다
문자열 stl 구현해보기
String이란 이름의 클래스를 생성해주고 문자열의 사이즈를 반환할 변수 & 문자열을 동적으로 생성할 pointer 포인터를 선언해준다
생성자에서 초기화 해주기
#include <iostream>
using namespace std;
class String
{
private:
int size;
// 문자열을 동적으로 생성할 포인터
char* pointer;
public:
String()
{
size = 0;
pointer = nullptr;
}
void operator = (const char* content)
{
size = strlen(content) + 1;
if (pointer == nullptr)
{
pointer = new char[size];
for (int i = 0; i < size; i++)
{
pointer[i] = content[i];
}
}
else
{
// 새로운 배열
char* newpointer;
newpointer = new char[size];
for (int i = 0; i < size; i++)
{
newpointer[i] = content[i];
}
// 기존의 배열 해제
delete[] pointer;
pointer = newpointer;
}
}
int maine()
{
String string;
string = "BABABA";
}
만약 pointer가 가리키는 곳이 nullptr이라면 -> 문자열이 하나도 없다는 것
-> 동적으로 새 배열을 만들고 크기를 할당해주어야함
새로 동적할당한 배열을 pointer로 접근해서 인수로 들어온 content의 문자열을 하나씩 넣어준다
if (pointer == nullptr)
{
pointer = new char[size];
for (int i = 0; i < size; i++)
{
pointer[i] = content[i];
}
}
새로운 포인터를 하나 만들어서 동적배열을 할당해준다
새로운 동적배열에 인수로 들어온 content의 문자열을 할당해주고 기존의 배열을 해제한다


newpointer 포인터는 함수안에서 생성했기 때문에 함수가 종료되면 사라진다. 따라서 pointer 포인터만 새로 할당된 배열을 가리킨다
메인함수에서 작동했을 때, 문자열이 바뀌는 것을 알 수 있다
ex) 기존에 Banana 문자열은 사라지고 Milk로 변경된다
int main()
{
String string;
string = "Banana";
string = "Milk";
}
void Append(const char* word)
{
// 기존 크기 + 매개변수 문자 크기
size = strlen(word) + strlen(pointer) + 1;
char* newPointer = new char[size];
// 기존 값 넣기
for (int i = 0; i < strlen(pointer); i++)
{
newPointer[i] = pointer[i];
}
// 추가된 값 넣기
for (int i = 0; i < strlen(word); i++)
{
newPointer[strlen(pointer) + i] = word[i];
}
delete[] pointer;
pointer = newPointer;
}

// 추가된 값 넣기
for (int i = 0; i < strlen(word); i++)
{
newPointer[strlen(pointer) + i] = word[i];
}
함수의 반환형은 int로
문자열이 서로 같으면 0
현재 문자열 > 새로 들어온 문자열 1
현재 문자열 < 새로 들어온 문자열 -1 을 반환
문자열의 길이가 서로 다를 경우, 값이 제대로 나오지 않아 추가적인 조건을 더 넣어주었다
현재 문자열의 길이 > 새로 들어온 문자열의 길이 1
현재 문자열의 길이 < 새로 들어온 문자열의 길이 -1 반환
// 둘이 같으면 0 현재pointer> 새로word 1 / -1
int Compare(const char* word)
{
int count = 0;
for (int i = 0; i < strlen(word); i++)
{
if (pointer[i] != word[i])
{
break;
}
else
{
count++;
}
}
if (strlen(word) == count)
{
return 0;
}
int thisString = 0;
int otherString = 0;
for (int i = 0; i < strlen(pointer); i++)
{
thisString += pointer[i];
}
for (int i = 0; i < strlen(word); i++)
{
otherString += word[i];
}
if (thisString > otherString)
{
return 1;
}
else
{
return -1;
}
}
두 문자열을 비교하여 하나라도 다르면 바로 break로 반복문을 빠져나오고 같은 문자열이 있다면 count증가
count값이 strlen(word)와 같다는 건 문자열이 동일하다는 의미 return 0
문자열이 서로 다를 경우 break로 반복문을 빠져나온 뒤 아래의 반복문 진입
각각의 문자열들의 값을 int형으로 누적시킨다
두 문자열의 아스키코드 값으로 비교하여 값을 return
// 인덱스 값 반환
const char& operator [] (const int& index)
{
return pointer[index];
}
~String()
{
if (pointer != nullptr)
{
delete[] pointer;
}
}
const int& Size()
{
// null문자 제외
return size - 1;
}
String 클래스 타입의 객체를 생성해주고 대입연산자 오버로딩을 통해 객체에 값을 대입
string = "APPLE"; 을 대입한 뒤 값을 바꿔 string = "BANANA";로 대입 할 경우 기존의 APPLE 문자열은 해제되고 새로운 문자열이 할당된다
문자열 비교함수인 Compare쪽에선 현재 문자열보다 비교할 문자열의 길이가 더 길기 때문에 결과값이 -1이 나와야한다
int main()
{
String string;
string = "APPLE";
for (int i = 0; i < string.Size(); i++)
{
cout << string[i];
}
cout << endl;
string = "BANANA";
string.Append("MILK");
for (int i = 0; i < string.Size(); i++)
{
cout << string[i];
}
cout << endl;
string = "ABCD";
cout << string.Compare("ABCCCCCC");
return 0;
}
출력값:
string에 += 으로 '문자'나 "문자열"을 추가할 수 있다.
string s = "hi";
s += '!';
s += "Hello";
cout << s; // "hi!Hello"
string에 push_back()으로 문자 추가 시 char 만 가능하다. 문자열 불가능
string s = "abc";
s += 'd'; // OK → "abcd"
s += "efg"; // OK → "abcdefg"
s.push_back('h'); // OK → "abcdefgh"
s.push_back("ij"); // ❌ 컴파일 에러 (char*는 안 됨)