[C/C++] string

할랑말랑·2026년 3월 12일

C/C++

목록 보기
22/45

string 클래스

C++에서 문자열을 효율적으로 다루는 클래스
다양한 함수와 연산자를 제공하여 문자열 조작을 용이하게 한다.

특징

  • 동적 크기 : 필요에 따라 크기를 자동으로 조절
  • 문자열 리터럴 : 문자열 리터럴과 쉽게 변환하고 연결할 수 있다.
  • 복사 및 이동 : 복사 생성자와 이동 생성자를 제공하여 효율적인 메모리 관리를 지원

주요 멤버함수

1. 생성자 / 할당 및 초기화

#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;
}

2. 접근자

#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;
}

3. 문자열 수정

#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;
}

4. 검색

#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;
}

5. 길이 및 용량

#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;
}

6. 반복자

  • begin() : 시작 반복자
  • end() : 끝 반복자
  • rbegin() : 역방향 시작 반복자
  • rend() : 역방향 끝 반복자
  • cbegin() : 시작 반복자 (상수)
  • cend() : 끝 반복자 (상수)
  • crbegin() : 역방향 시작 반복자 (상수)
  • crend() : 역방향 끝 반복자 (상수)

7. 비교

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;
}

8. 기타

#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;
}

참고

  • invalid_argument 예외 : 변환 자체가 불가능할 때
  • out_of_range 예외 : 변환은 가능하지만 타입 범위를 초과할 때

0개의 댓글