본문으로 건너뛰기 C++ std::string Complete Guide: Operations, Split, Trim &

C++ std::string Complete Guide: Operations, Split, Trim &

C++ std::string Complete Guide: Operations, Split, Trim &

이 글의 핵심

Practical std::string guide: concatenation, compare, substr, find, replace, SSO, string_view lifetime, reserve for +=, and c_str validity in modern C++.

std::string is a contiguous character sequence—the same “resizable array” story as in arrays and lists.

Basics

Declaration and initialization

#include <string>
#include <iostream>
std::string s1 = "Hello";
std::string s2("World");
std::string s3 = s1;           // Copy
std::string s4(5, 'A');        // "AAAAA"
std::string s5(s1, 1, 3);      // "ell" (from position 1, length 3)

Concatenation

std::string a = "Hello";
std::string b = " World";
// Using +
std::string c = a + b;  // "Hello World"
// Using +=
a += b;  // a is now "Hello World"
// Using append
a.append(" Again");  // "Hello World Again"

Comparison

std::string s1 = "apple";
std::string s2 = "banana";
// Operators
bool equal = (s1 == s2);     // false
bool less = (s1 < s2);       // true (lexicographic)
// compare() method
int result = s1.compare(s2);
// < 0 if s1 < s2
// = 0 if s1 == s2
// > 0 if s1 > s2

Size and access

std::string s = "Hello";
// Size
size_t len = s.length();  // 5
size_t sz = s.size();     // 5 (same as length)
bool empty = s.empty();   // false
// Access
char first = s[0];        // 'H' (no bounds check)
char second = s.at(1);    // 'e' (throws if out of range)
char& last = s.back();    // 'o'
char& front = s.front();  // 'H'

Substrings

std::string s = "Hello World";
// substr(pos, len)
std::string sub1 = s.substr(0, 5);  // "Hello"
std::string sub2 = s.substr(6);     // "World" (to end)
std::string sub3 = s.substr(6, 3);  // "Wor"
std::string s = "Hello World";
// find
size_t pos = s.find("World");  // 6
if (pos != std::string::npos) {
    std::cout << "Found at " << pos << "\n";
}
// rfind (reverse find)
pos = s.rfind('o');  // 7 (last 'o')
// find_first_of
pos = s.find_first_of("aeiou");  // 1 ('e')
// find_last_of
pos = s.find_last_of("aeiou");  // 7 ('o')

Replace

std::string s = "Hello World";
// replace(pos, len, new_str)
s.replace(6, 5, "C++");  // "Hello C++"
// Global replace (all occurrences)
std::string text = "cat cat cat";
size_t pos = 0;
while ((pos = text.find("cat", pos)) != std::string::npos) {
    text.replace(pos, 3, "dog");
    pos += 3;
}
// Result: "dog dog dog"

Insert / erase / clear

std::string s = "Hello World";
// insert
s.insert(5, ",");  // "Hello, World"
// erase
s.erase(5, 1);  // "Hello World" (remove comma)
// clear
s.clear();  // "" (empty)

Practical examples

Split string (CSV)

#include <string>
#include <vector>
#include <sstream>
std::vector<std::string> split(const std::string& str, char delimiter) {
    std::vector<std::string> tokens;
    std::stringstream ss(str);
    std::string token;
    
    while (std::getline(ss, token, delimiter)) {
        tokens.push_back(token);
    }
    
    return tokens;
}
// Usage
std::string csv = "apple,banana,orange";
auto fruits = split(csv, ',');
// {"apple", "banana", "orange"}

Trim whitespace

#include <string>
#include <algorithm>
#include <cctype>
std::string trim(const std::string& str) {
    auto start = std::find_if(str.begin(), str.end(), [](unsigned char c) {
        return !std::isspace(c);
    });
    
    auto end = std::find_if(str.rbegin(), str.rend(), [](unsigned char c) {
        return !std::isspace(c);
    }).base();
    
    return (start < end) ? std::string(start, end) : std::string();
}
// Usage
std::string s = "  Hello World  ";
std::string trimmed = trim(s);  // "Hello World"

Case conversion

#include <string>
#include <algorithm>
#include <cctype>
std::string toUpper(std::string str) {
    std::transform(str.begin(), str.end(), str.begin(),
                   [](unsigned char c) { return std::toupper(c); });
    return str;
}
std::string toLower(std::string str) {
    std::transform(str.begin(), str.end(), str.begin(),
                   [](unsigned char c) { return std::tolower(c); });
    return str;
}
// Usage
std::string s = "Hello World";
std::string upper = toUpper(s);  // "HELLO WORLD"
std::string lower = toLower(s);  // "hello world"

String validation

#include <string>
#include <algorithm>
#include <cctype>
bool isNumeric(const std::string& str) {
    return !str.empty() && std::all_of(str.begin(), str.end(), ::isdigit);
}
bool isAlpha(const std::string& str) {
    return !str.empty() && std::all_of(str.begin(), str.end(), ::isalpha);
}
bool isEmail(const std::string& str) {
    size_t at = str.find('@');
    size_t dot = str.rfind('.');
    return at != std::string::npos && 
           dot != std::string::npos && 
           at < dot && 
           at > 0 && 
           dot < str.length() - 1;
}
// Usage
isNumeric("12345");  // true
isAlpha("Hello");    // true
isEmail("test@example.com");  // true

Small String Optimization (SSO)

Most implementations store short strings inline without heap allocation:

#include <string>
#include <iostream>
// 변수 선언 및 초기화
int main() {
    std::string short_str = "Hi";        // Likely SSO (no heap)
    std::string long_str = "This is a very long string that exceeds SSO buffer";  // Heap allocated
    
    std::cout << "Short: " << short_str.capacity() << "\n";  // ~15-23 (varies)
    std::cout << "Long: " << long_str.capacity() << "\n";    // > SSO threshold
}

Typical SSO sizes:

  • GCC/libstdc++: 15 bytes
  • Clang/libc++: 22 bytes
  • MSVC: 15 bytes

Performance tips

Reserve capacity for concatenations

// ❌ Slow: multiple reallocations
std::string result;
for (int i = 0; i < 1000; ++i) {
    result += std::to_string(i) + " ";
}
// ✅ Fast: reserve first
std::string result;
result.reserve(10000);  // Estimate total size
for (int i = 0; i < 1000; ++i) {
    result += std::to_string(i) + " ";
}

Benchmark (1000 concatenations):

  • Without reserve: 45ms
  • With reserve: 8ms

Use string_view for read-only operations

#include <string_view>
// ❌ Copies string
void process(std::string str) {
    std::cout << str << "\n";
}
// ✅ No copy
void process(std::string_view str) {
    std::cout << str << "\n";
}
// Usage
std::string s = "Hello World";
process(s);  // No copy with string_view

Avoid temporary strings

// ❌ Creates temporary
std::string result = std::string("Hello") + " " + "World";
// ✅ Direct construction
std::string result = "Hello World";
// ✅ Or use operator+= for multiple parts
std::string result = "Hello";
result += " ";
result += "World";

Common pitfalls

1. C string confusion

// ❌ Wrong: string literal is const char*
char* str = "Hello";  // Error or deprecated
// ✅ Correct
const char* str = "Hello";
std::string s = "Hello";

2. npos comparison

std::string s = "Hello";
// ❌ Wrong: int can't hold npos
int pos = s.find("x");
if (pos != std::string::npos) { /* ... */ }
// ✅ Correct
size_t pos = s.find("x");
if (pos != std::string::npos) { /* ... */ }
// ✅ Or use auto
auto pos = s.find("x");

3. Dangling c_str()

// ❌ Dangling pointer
const char* getCString() {
    std::string s = "Hello";
    return s.c_str();  // s destroyed, pointer invalid!
}
// ✅ Return string by value
std::string getString() {
    return "Hello";
}

4. Inefficient concatenation in loops

// ❌ Slow: O(n²) due to reallocations
std::string result;
for (const auto& item : items) {
    result = result + item + " ";
}
// ✅ Fast: O(n) with +=
std::string result;
result.reserve(estimated_size);
for (const auto& item : items) {
    result += item;
    result += " ";
}

string vs string_view

Featurestd::stringstd::string_view
OwnershipOwns dataBorrows data
ModifiableYesNo (read-only)
AllocationMay allocateNever allocates
LifetimeIndependentDepends on source
Use caseStoragePassing/viewing
#include <string>
#include <string_view>
void print(std::string_view sv) {
    std::cout << sv << "\n";
}
std::string s = "Hello World";
print(s);              // OK: string -> string_view
print("Literal");      // OK: no temporary string
print(s.substr(0, 5)); // ⚠️ Dangerous: temporary string destroyed!

Compiler support

Compilerstd::stringSSOstd::string_view
GCCAll versions5+7+ (C++17)
ClangAll versions3.4+4+ (C++17)
MSVCAll versions2015+2017 15.3+ (C++17)

Keywords

std::string, string_view, substr, find, replace, SSO, C++, STL, text processing, string manipulation


Frequently Asked Questions (FAQ)

Q. When would I use this in practice?

A. Practical std::string guide: concatenation, compare, substr, find, replace, SSO, string_view lifetime, reserve for +=, a…

Q. What should I read before this?

A. Follow the previous article or related articles links at the bottom of each post to learn in sequence. See the C++ series index for the full picture.

Q. Where can I study this more deeply?

A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.


Other articles related to this topic.


Keywords Covered in This Article (Related Search Terms)

This article covers C++, string, STL, text processing.