一、為什麼選擇 std::string?
相比 char*,std::string 自動管理記憶體,無需手動計算長度、擴容、釋放,提供豐富的操作符(=、==、+、+=)與成員函數,幾乎覆蓋所有字符串處理需求,可視為 C++ 的基本數據類型使用。
二、頭文件與命名空間
#include <string> // 注意:不是 string.h (C 風格)
using std::string; // 或 using namespace std;
三、構造函數全覽
| 形式 | 代碼 | 說明 |
| 默認 | string s; | 空字符串 |
| 拷貝 | string s(str); | 復制構造 |
| 子串構造 | string s(str, pos); | 從 pos 到末尾 |
| 子串長度 | string s(str, pos, len); | 從 pos 取 len 字符 |
| C 字符串 | string s(cstr); | 以 '\0' 結尾 |
| C 字符串前 n 字符 | string s(cstr, n); | 不要求 '\0' |
| 重複字符 | string s(n, 'x'); | n 個 'x' |
| 迭代器區間 | string s(beg, end); | [beg, end) |
四、核心操作函數分類速查
1. 賦值與交換
s = "abc" / s.assign("abc")
s.swap(s2):常數時間交換內容,不拷貝數據。
2. 追加與插入
s += "tail" / s.append("tail") / s.push_back('c')
s.insert(pos, "mid"):在 pos 前插入。
3. 刪除與清空
s.erase(pos, len)、s.clear()
4. 替換
s.replace(pos, len, "new")
5. 拼接與比較
s3 = s1 + s2(返回新對象)
==, !=, <, >, compare():字典序比較。
6. 大小與容量
size() / length():當前字符數。
empty():是否為空。
capacity():重新分配前可容納字符數。
reserve(n):預留空間,避免頻繁擴容。
max_size():理論最大長度。
7. 元素存取
s[i]:無邊界檢查,s.at(i):拋出 out_of_range。
8. C 風格互轉(重點)
| 函數 | 返回類型 | 特點 |
c_str() | const char* | 以 '\0' 結尾,安全,推薦用於 C API。 |
data() | const char* | C++11 前不保證 '\0',C++11 起同 c_str()。 |
copy(buf, len, pos) | size_t | 復制到用戶緩衝區,不加 '\0',需手動添加。 |
// 安全調用 C API
void LegacyAPI(const char* p);
string s = "hello";
LegacyAPI(s.c_str()); // 正確
// 若 C API 會修改緩衝區,必須拷貝
vector<char> buf(s.begin(), s.end());
buf.push_back('\0');
LegacyAPI(buf.data()); // 或 &buf[0]
9. 子串與查找
s.substr(pos, len):返回新 string。
find、rfind、find_first_of、find_last_of、find_first_not_of、find_last_not_of:返回 size_t,未找到返回 npos。
10. 迭代器支援
begin()/end()、rbegin()/rend():可配合 STL 算法(sort、reverse 等)。
五、實戰範例:常見操作綜合演示
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
string s = "Hello";
s += ", World!"; // 追加
s.insert(5, " C++"); // 插入 -> "Hello C++, World!"
cout << s << '\n';
string sub = s.substr(0, 5); // "Hello"
cout << "Sub: " << sub << '\n';
size_t pos = s.find("C++");
if (pos != string::npos)
cout << "Found at: " << pos << '\n';
// 大小寫轉換(需自行實現或用 boost/locale)
transform(s.begin(), s.end(), s.begin(), ::toupper);
cout << "Upper: " << s << '\n';
// C API 互操作
const char* c = s.c_str();
printf("C style: %s\n", c);
return 0;
}
六、性能優化建議
- 預留容量:已知大致長度時用
reserve(),減少擴容拷貝。
- 避免不必要的拷貝:函數參數用
const string&,返回值利用移動語義(C++11 起自動優化)。
- 字符串拼接:大量拼接用
ostringstream 或 string::append,避免 s = s + "x" 產生臨時對象。
- 短字符串優化 (SSO):現代實現對短字符串(通常 ≤15/22 字符)不分配堆內存,直接存於對象內部,極大提升性能。
七、常見錯誤與避坑
- 修改
c_str() 返回指針:行為未定義,嚴禁 const_cast 後寫入。
- 迭代器失效:任何可能導致重新分配的操作(
append、insert、reserve 等)都會使迭代器、指針、引用失效。
data() 在 C++11 前不保證 '\0':跨標準庫版本移植時慎用。
- 混用有符號/無符號索引:
size_t 為無符號,反向循環需注意 i >= 0 永真,改用 for (auto it = s.rbegin(); it != s.rend(); ++it)。
std::string 是 C++ 標準庫中設計最精良、使用最頻繁的組件之一。深入掌握其構造、操作、轉換規則與性能特性,能讓你編寫出更安全、高效、可維護的 C++ 代碼。
- 上一篇文章: C++ STL vector 完全指南:從基礎操作到多維動態數組實戰
- 下一篇文章: C 語言實現集合運算:有序鏈表實現並集、交集、差集
Copyright ©
程式碼之家 All Rights Reserved