C++에서 문자열을 효율적으로 다루는 클래스
다양한 함수와 연산자를 제공하여 문자열 조작을 용이하게 한다.
#include <iostream>
#include <string>
int main()
{
// 기본 생성자 : 빈 문자열 생성
std::string s1;
// 초기화 리스트로 생성
std::string s2 = { "감자" };
// 복사 생성자
std::string s3 = s2;
// 이동 생성자
std::string s4 = std::move(s2);
// 복사 대입 연산자
std::string s5;
s5 = s3;
// 이동 대입 연산자
std::string s6;
s6 = std::move(s5);
// assign() : 문자열 할당
std::string s7;
s7.assign("고구마");
// string(const char*) : C 문자열로 생성
std::string s8("참치");
// string(size_t n, char c) : 문자 c를 n개 반복
std::string s9('a', 6);
return 0;
}
#include <iostream>
#include <string>
int main()
{
std::string str6;
str6 = "asas";
// 접근자 at(size_t pos) : 특정 위치에 있는 문자를 반환
// 유효하지 않은 인덱스에 접근할 경우 std::out_of_range 예외를 발생시킨다.
// try-catch 블록을 사용하여 예외를 처리함으로 프로그램이 중단되지 않고, 적절하게 처리 가능하다.
try
{
char ch = str6.at(0);
std::cout << "at(0) : index 0번째 문자 반환 " << ch << std::endl;
ch = str6.at(5);
}
catch (std::out_of_range)
{
std::cout << "범위 체크로 예외 처리 가능" << std::endl;
}
// 연산자 오버로딩 [](size_t pos) : 특정 위치에 있는 문자를 반환
// 연산자 오버로딩은 범위 체크를 하지 않기 때문에 유효하지 않은 인덱스에 접근시 프로그램이 중단된다.
std::cout << "str6[4] : " << str6[3] << std::endl;
// front() : 첫 번째 문자 반환
// back() : 마지막 문자 반환
// 문자열이 있는지 확인후 사용해야한다.
std::cout << "str6.front() : " << str6.front() << std::endl;
std::cout << "str6.back() : " << str6.back() << std::endl;
return 0;
}
#include <iostream>
#include <string>
int main()
{
// --- 문자열 수정 (insert, erase, replace, append) ---
std::string str6 = "asas";
std::cout << "초기 str6 : " << str6 << std::endl;
// append() - 문자열 끝에 문자열을 추가
str6.append("zxzx");
std::cout << "append() 후 : " << str6 << std::endl; // 출력: asaszxzx
// insert() - 지정한 위치에 문자열을 삽입
str6.insert(1, "BBBB");
std::cout << "insert() 후 : " << str6 << std::endl; // 출력: aBBBBsaszxzx
// erase() - 지정된 위치의 문자를 삭제
str6.erase(1, 4); // index 1부터 4개의 문자("BBBB") 삭제
std::cout << "erase() 후 : " << str6 << std::endl; // 출력: asaszxzx
// replace() - 지정된 부분을 다른 문자열로 대체
str6.replace(0, 1, "1"); // index 0부터 1개의 문자("a")를 "1"로 대체
std::cout << "replace() 후 : " << str6 << std::endl; // 출력: 1saszxzx
std::cout << "--------------------------" << std::endl;
// --- 문자열 추가, 삭제, 교환 ---
std::string s1 = { "감자" };
std::string s2("고구마");
std::string s3("튀김");
std::cout << "초기 s1: " << s1 << ", s3: " << s3 << std::endl;
// operator+= : 문자열 추가 (append와 유사)
s1 += "참치";
s1 += s2;
std::cout << "operator+= 후 s1 : " << s1 << std::endl; // 출력: 감자참치고구마
// push_back() : 문자 하나 추가
s1.push_back('1');
std::cout << "push_back('1') 후 s1 : " << s1 << std::endl; // 출력: 감자참치고구마1
// pop_back() : 마지막 문자 삭제
s1.pop_back();
std::cout << "pop_back() 후 s1 : " << s1 << std::endl; // 출력: 감자참치고구마
// swap() : 두 문자열 교환
s1.swap(s3);
std::cout << "swap() 후 s1 : " << s1 << std::endl; // 출력: 튀김
std::cout << "swap() 후 s3 : " << s3 << std::endl; // 출력: 감자참치고구마
return 0;
}
#include <iostream>
#include <string>
int main()
{
// --- find, rfind, find_first_of, find_last_of 예제 ---
std::string str6;
str6 = "asas";
// find() - 특정 문자열 또는 문자 검색
// 찾으면 문자,문자열 위치 반환 / 없으면 -1 반환한다.
int index = str6.find("1");
std::cout << "찾은 위치 반환 : " << index << std::endl;
index = str6.find("a");
std::cout << "찾은 위치 반환 : " << index << std::endl;
// rfind() - 뒤에서부터 문자/문자열 검색한다.
// 찾으면 문자,문자열 위치 반환 / 없으면 -1 반환한다.
index = str6.rfind("a");
std::cout << "찾은 위치 반환 : " << index << std::endl;
// find_first_of() - 특정 문자/문자열의 첫번째 위치 검색
// find_last_of() - 특정 문자/문자열의 마지막 위치 검색
// 찾는문자나 문자열이 없으면 -1 반환한다.
index = str6.find_first_of("a");
std::cout << "찾은 첫번째 위치 반환 : " << index << std::endl;
index = str6.find_last_of("a");
std::cout << "찾은 마지막 위치 반환 : " << index << std::endl;
std::cout << "\n----------------------------------------\n" << std::endl;
// --- find_first_not_of, find_last_not_of 예제 ---
std::string s1 = { "12az8437:383a21l1" };
// 함수 원형
// size_t find_first_not_of(const string & str, size_t pos = 0) const;
// size_t find_first_not_of(const char* s, size_t pos = 0) const;
// size_t find_first_not_of(const char* s, size_t pos, size_t n) const;
// size_t find_first_not_of(const char c, size_t pos = 0) const;
// str/s/c : 검색에서 제외할 문자들의 집합
// pos : 검색을 시작할 위치 (기본값: 0)
// n : 문자 배열에서 고려할 문자 수
// find_first_not_of() : 문자열에서 지정된 문자들에 포함되지 않는 첫 번째 문자의 위치를 찾기
// 반환값 : 조건을 만족하는 첫 번째 문자의 인덱스 (size_t) / 찾지 못하면 std::string::npos 반환
size_t pos1 = s1.find_first_not_of("123456789");
if (pos1 != std::string::npos)
{
std::cout << pos1 << std::endl;
}
// find_last_not_of() : 주어진 문자 집합에 없는 마지막 문자 위치 찾기
// 반환값 : 조건을 만족하는 첫 번째 문자의 인덱스 (size_t) / 찾지 못하면 std::string::npos 반환
size_t pos2 = s1.find_last_not_of("123456789");
if (pos2 != std::string::npos)
{
std::cout << pos2 << std::endl;
}
return 0;
}
#include <iostream>
#include <string>
int main()
{
// --- size, length, capacity, resize 예제 ---
std::string str6 = "asas";
std::string str;
// size(),length() - 문자열의 길이를 반환한다.
std::cout << "str6 - size() : " << str6.size() << std::endl;
std::cout << "str6 - length() : " << str6.length() << std::endl;
std::cout << "str - size() : " << str.size() << std::endl;
// capacity() - 현재 할당된 메모리 크기 반환
std::cout << "str6 - capacity() : " << str6.capacity() << std::endl;
std::cout << "str - capacity() : " << str.capacity() << std::endl;
// resize() - 문자열 크기 조정
// 문자열 길이가 n보다 짧으면 문자열이 잘리며, 길이가 n보다 길면 잘리게 된다.
// resize(size_t n, char c): 문자열의 크기를 n으로 변경하며, 필요한 경우 c로 지정된 문자로 채워진다.
str.resize(10,'*');
std::cout << "str 문자열 : " << str << std::endl;
std::cout << "str - size() : " << str.size() << std::endl;
str.resize(5);
std::cout << "str 문자열 : " << str << std::endl;
std::cout << "str - size() : " << str.size() << std::endl;
std::cout << "\n----------------------------------------\n" << std::endl;
// --- empty, reserve, clear, shrink_to_fit 예제 ---
std::string s1 = { "12az8437:383a21l1" };
// empty() : 빈 문자열인지 확인
// 반환값 : 빈 문자열 true 아니면 false
bool check = s1.empty();
// void reserve(size_t n = 0) : 문자열 객체의 메모리 용량(capacity)을 미리 확보하여 재할당을 최소화
// n: 예약할 최소 용량 (문자 개수)
s1.reserve(30);
// 특징
// 성능 최적화: 여러 번의 메모리 재할당을 방지
// 비파괴적: 기존 문자열 내용 유지
// 예외 안전성: 메모리 할당 실패 시 std::length_error 또는 std::bad_alloc 예외 발생 가능
// void clear() noexcept : 문자열의 모든 내용을 삭제하여 빈 문자열로 만든다.
s1.clear();
// 문자열의 모든 문자를 제거
// size()를 0으로 만듬
// void shrink_to_fit() : 문자열 객체의 불필요한 메모리를 해제하여 capacity를 size에 맞게 줄인다.
// 사용하지 않는 예비 메모리를 반환
s1.shrink_to_fit();
return 0;
}
C++ 에서 std::string 객체는 사전식으로 비교(유니코드/아스키코드 값 기준)
문자열의 각 문자를 순서대로 비교한다.
#include <iostream>
#include <string>
int main()
{
std::string s1 = { "12" };
std::string s2 = s1;
std::string s3 = { "감자" };
std::string s4 = { "고구마" };
// operator== : 같은지 비교
if (s1 == s2)
{
std::cout << "s1 == s2" << std::endl;
}
// operator!= : 다른지 비교
if (s1 != s3)
{
std::cout << "s1 != s3" << std::endl;
}
// operator> : 사전식 순서로 큰지 비교
if (s3 > s4)
{
std::cout << "s3 > s4" << std::endl;
}
// operator< : 사전식 순서로 작은지 비교
if (s3 < s4)
{
std::cout << "s3 < s4" << std::endl;
}
// operator>= : 사전식 순서로 크거나 같은지 비교
if (s3 >= s4)
{
std::cout << "s3 >= s4" << std::endl;
}
// operator<= : 사전식 순서로 작거나 같은지 비교
if (s3 <= s4)
{
std::cout << "s3 <= s4" << std::endl;
}
// 1. 전체 문자열 비교
// int compare(const string & str) const
// int compare(const char* s) const
// 2. 부분 문자열 비교
// int compare(size_t pos, size_t len, const string & str) const
// int compare(size_t pos, size_t len, const char* s) const
// 3. 부분 문자열끼리 비교
// int compare(size_t pos, size_t len, const string & str, size_t subpos, size_t sublen) const
// int compare(size_t pos, size_t len, const char* s, size_t n) const
// str: 비교할 문자열
// s: 비교할 C 스타일 문자열
// pos: 비교를 시작할 위치
// len: 비교할 문자 개수
// subpos: 비교 대상 문자열의 시작 위치
// sublen: 비교 대상 문자열의 길이
// compare() : 두 문자열을 사전식(lexicographical) 순서로 비교하여 정수 값을 반환
// 반환값
// 0 : 두 문자열이 같음
// 음수 (< 0) : 호출 문자열이 비교 문자열보다 사전식으로 앞섬
// 양수 (> 0) : 호출 문자열이 비교 문자열보다 사전식으로 뒤섬
s1.compare(s2);
return 0;
}
#include <iostream>
#include <string>
int main()
{
// --- substr, to_string 및 문자열 변환 함수 예제 ---
std::string s1 = { "Hello World!" };
// string substr(size_t pos = 0, size_t len = npos) const : 문자열의 일부분을 추출하여 새로운 문자열 객체를 반환
// pos: 부분 문자열의 시작 위치 (0부터 시작, 기본값: 0)
// len: 추출할 문자 개수 (기본값: npos, 즉 끝까지)
// 추출된 부분 문자열을 담은 새로운 string 객체
// pos가 문자열 길이보다 크면 out_of_range 예외 발생
std::string s2 = s1.substr(2, 6);
std::cout << s2 << std::endl;
// to_string() - 수치를 문자열로 변환
std::string s3 = std::to_string(10);
// stoi() : 문자열을 int로 변환
// int stoi(const string & str, size_t * pos = 0, int base = 10)
// int stoi(const wstring & str, size_t * pos = 0, int base = 10)
int i1 = std::stoi("1");
// long stol(const string& str, size_t* pos = 0, int base = 10) : 문자열을 long으로 변환
long l1 = std::stol("3147483648");
// long long stoll(const string & str, size_t * pos = 0, int base = 10) : 문자열을 long long으로 변환
long long ll1 = std::stoll("31474836481212");
// float stof(const string & str, size_t * pos = 0) : 문자열을 float로 변환
float f1 = std::stof("3.41");
// double stod(const string & str, size_t * pos = 0) : 문자열을 double로 변환
double d1 = std::stod("3.123455534332");
std::cout << "\n----------------------------------------\n" << std::endl;
// --- c_str, data 예제 ---
std::string str6;
str6 = "asas";
// c_str() - std::string 객체를 c스타일 문자열로 변환한다.
const char* cstr = str6.c_str();
std::cout << cstr << std::endl;
// data() - std::string 객체의 문자열의 포인터를 반환한다.
char* cstr1 = &str6[0]; // C++11 이전 버전 호환성을 위해 &str6[0] 사용 권장
// char* cstr1 = str6.data(); // C++17 부터는 널 종결을 보장하며 비-상수 포인터 반환
std::cout << cstr1 << std::endl;
return 0;
}