icon안동민 개발노트

std::string 클래스


std::string 개요

 std::string은 C++의 표준 라이브러리에서 제공하는 문자열 클래스입니다.

 이 클래스는 C 스타일 문자열의 한계를 극복하고 더 안전하고 편리한 문자열 처리를 가능하게 합니다.

 std::string은 <string> 헤더에 정의되어 있습니다.

std::string의 특징

 1. 동적 크기 조정 : 문자열의 길이가 자동으로 관리됩니다.

 2. 안전한 메모리 관리 : 메모리 누수와 버퍼 오버플로우 위험을 줄여줍니다.

 3. 풍부한 멤버 함수 : 다양한 문자열 조작 기능을 제공합니다.

 4. 연산자 오버로딩 : 직관적인 문자열 연산이 가능합니다.

 5. 표준 컨테이너와의 호환성 : STL 알고리즘과 함께 사용할 수 있습니다.

std::string 사용하기

 헤더 파일 포함

#include <string>

 문자열 생성과 초기화

#include <iostream>
#include <string>
 
int main() {
    std::string s1 = "Hello";
    std::string s2("World");
    std::string s3(5, 'a');  // "aaaaa"
 
    std::cout << "s1: " << s1 << std::endl;
    std::cout << "s2: " << s2 << std::endl;
    std::cout << "s3: " << s3 << std::endl;
 
    return 0;
}

 문자열 연결

#include <iostream>
#include <string>
 
int main() {
    std::string s1 = "Hello";
    std::string s2 = "World";
    std::string result = s1 + " " + s2;
 
    std::cout << "연결된 문자열: " << result << std::endl;
 
    return 0;
}

주요 멤버 함수

 length()size()

 기능 : 문자열의 길이를 반환합니다.

 설명 : 두 함수는 동일한 기능을 수행하며, 현재 문자열에 포함된 문자의 개수를 반환합니다. null 종료 문자는 포함되지 않습니다.

#include <iostream>
#include <string>
 
int main() {
    std::string str = "Hello, World!";
    std::cout << "문자열 길이: " << str.length() << std::endl;
    std::cout << "문자열 크기: " << str.size() << std::endl;
 
    return 0;
}

 empty() 함수

 기능 : 문자열이 비어있는지 확인합니다.

 설명 : 문자열의 길이가 0이면 true를, 그렇지 않으면 false를 반환합니다.

#include <iostream>
#include <string>
 
int main() {
    std::string str1;
    std::string str2 = "Hello";
 
    std::cout << "str1 is empty: " << (str1.empty() ? "Yes" : "No") << std::endl;
    std::cout << "str2 is empty: " << (str2.empty() ? "Yes" : "No") << std::endl;
 
    return 0;
}

 substr(pos, len) 함수

 기능 : 문자열의 일부분을 추출합니다.

 설명 : pos 위치부터 시작하여 len 길이만큼의 부분 문자열을 반환합니다. len을 생략하면 문자열의 끝까지 추출합니다.

#include <iostream>
#include <string>
 
int main() {
    std::string str = "Hello, World!";
    std::string sub = str.substr(7, 5);  // 시작 위치 7, 길이 5
 
    std::cout << "부분 문자열: " << sub << std::endl;
 
    return 0;
}

 find(str, pos) 함수

 기능 : 문자열에서 특정 부분 문자열을 검색합니다.

 설명 : str을 pos 위치부터 검색하여 첫 번째로 일치하는 위치를 반환합니다. 찾지 못하면 std::string::npos를 반환합니다.

#include <iostream>
#include <string>
 
int main() {
    std::string str = "Hello, World!";
    size_t pos = str.find("World");
 
    if (pos != std::string::npos) {
        std::cout << "Found at position: " << pos << std::endl;
    } else {
        std::cout << "Not found" << std::endl;
    }
 
    return 0;
}

 replace(pos, len, str) 함수

 기능 : 문자열의 일부를 다른 문자열로 교체합니다.

 설명 : pos 위치부터 len 길이만큼의 부분을 str로 교체합니다.

#include <iostream>
#include <string>
 
int main() {
    std::string str = "Hello, World!";
    str.replace(7, 5, "C++");
 
    std::cout << "변경된 문자열: " << str << std::endl;
 
    return 0;
}

문자열 반복과 접근

 인덱스 기반 접근

#include <iostream>
#include <string>
 
int main() {
    std::string str = "Hello";
    for (size_t i = 0; i < str.length(); ++i) {
        std::cout << str[i] << " ";
    }
    std::cout << std::endl;
 
    return 0;
}

 범위 기반 for 루프

#include <iostream>
#include <string>
 
int main() {
    std::string str = "Hello";
    for (char c : str) {
        std::cout << c << " ";
    }
    std::cout << std::endl;
 
    return 0;
}

C 스타일 문자열과의 상호 운용

 std::string에서 C 스타일 문자열로

#include <iostream>
#include <string>
#include <cstring>
 
int main() {
    std::string str = "Hello";
    const char* cstr = str.c_str();
 
    std::cout << "C 스타일 문자열: " << cstr << std::endl;
    std::cout << "길이: " << std::strlen(cstr) << std::endl;
 
    return 0;
}

 C 스타일 문자열에서 std::string으로

#include <iostream>
#include <string>
 
int main() {
    const char* cstr = "Hello";
    std::string str(cstr);
 
    std::cout << "std::string: " << str << std::endl;
 
    return 0;
}

문자열 스트림

 문자열 스트림을 사용하면 다양한 데이터 타입을 쉽게 문자열로 변환할 수 있습니다.

#include <iostream>
#include <sstream>
#include <string>
 
int main() {
    std::stringstream ss;
    int age = 25;
    double height = 180.5;
 
    ss << "Age: " << age << ", Height: " << height;
    std::string result = ss.str();
 
    std::cout << result << std::endl;
 
    return 0;
}

성능 고려사항

  1. 작은 문자열 최적화 (Small String Optimization, SSO) : 대부분의 std::string 구현은 짧은 문자열을 위한 최적화를 포함합니다.
  2. 문자열 연결 시 += 연산자 vs append() 메서드 : 큰 차이는 없지만, append()가 약간 더 효율적일 수 있습니다.
  3. 대량의 문자열 처리 시 reserve() 사용 : 미리 메모리를 할당하여 재할당 횟수를 줄일 수 있습니다.

append(str) 함수

 기능 : 현재 문자열의 끝에 다른 문자열을 추가합니다.

 설명 : += 연산자와 유사하지만, 여러 가지 오버로드된 버전이 있어 더 유연하게 사용할 수 있습니다.

reserve(n) 함수

 기능 : 문자열을 위한 메모리를 미리 할당합니다.

 설명 : 최소한 n개의 문자를 저장할 수 있는 메모리를 할당합니다. 이는 많은 문자를 추가할 때 재할당을 줄여 성능을 향상시킵니다.

std::string str;
str.reserve(1000);  // 1000 문자를 위한 공간 예약

C++ 17 string_view

 string_view는 문자열의 읽기 전용 뷰를 제공하여 성능을 향상시킬 수 있습니다.

#include <iostream>
#include <string_view>
 
void printSubstring(std::string_view sv) {
    std::cout << sv.substr(0, 5) << std::endl;
}
 
int main() {
    std::string str = "Hello, World!";
    printSubstring(str);
 
    return 0;
}

연습 문제

  1. 사용자로부터 여러 단어를 입력받아 가장 긴 단어를 찾는 프로그램을 작성하세요.
  2. 주어진 문장에서 특정 단어를 다른 단어로 모두 치환하는 함수를 구현하세요.
  3. 문자열을 거꾸로 뒤집는 함수를 작성하고, 이를 이용하여 주어진 문자열이 회문(palindrome)인지 판단하는 프로그램을 개발하세요.
  4. 문자열에서 모든 공백을 제거하는 함수를 작성하세요.
  5. 두 문자열이 에너그램인지 확인하는 프로그램을 작성하세요. (에너그램 : 문자의 순서를 바꾸어 다른 단어를 만들 수 있는 단어)

 참고자료