當然可以!下面我將以系統全面、通俗易懂、深入淺出的方式,為你講解 C++ 中非常核心但也容易被低估的內容 —— std::string
。
🌟 C++ std::string
全面詳解
📌 一、string 是什么?
C++ 的 std::string
是 C++ 標準庫中封裝好的字符串類,本質是一個用于處理文本數據的容器。它定義在頭文件:
#include <string>
? 與 C 語言字符串的區別
特點 | C 字符串 (char[] ) | C++ 字符串 (std::string ) |
---|---|---|
存儲方式 | 字符數組 + 結束符 \0 | 類對象,有長度信息 |
可否動態擴展 | ? 不能自動擴展 | ? 自動擴展,支持追加 |
操作接口 | 函數庫函數(如 strcpy ) | 成員函數(如 .append() ) |
安全性 | 易越界、不安全 | 較安全,支持邊界檢查 |
📌 二、string 的常見構造方式
std::string s1; // 空字符串
std::string s2 = "hello"; // 從字符串字面值構造
std::string s3("world"); // 同上,直接構造
std::string s4(5, 'a'); // "aaaaa"
std::string s5 = s2 + s3; // 拼接字符串 "helloworld"
📌 三、常用操作方法與功能詳解
🧩 1. 訪問字符串內容
std::string str = "hello";
char c1 = str[1]; // 'e'
char c2 = str.at(1); // 更安全,帶邊界檢查
🧩 2. 修改字符串內容
str[0] = 'H'; // "Hello"
str.push_back('!'); // "Hello!"
str.pop_back(); // "Hello"
🧩 3. 添加和連接字符串
std::string s = "Hi";
s += " there"; // "Hi there"
s.append("!!!"); // "Hi there!!!"
🧩 4. 字符串長度
s.size(); // 字符個數(等同于 s.length())
s.empty(); // 是否為空
🧩 5. 查找與替換
std::string s = "I love C++";
size_t pos = s.find("love"); // 2
s.replace(pos, 4, "like"); // "I like C++"
find(str)
:返回首次出現位置rfind(str)
:返回最后一次出現的位置find_first_of(characters)
:任意字符第一次出現replace(pos, len, new_str)
:替換一部分內容
🧩 6. 子串操作
std::string s = "abcdef";
std::string sub = s.substr(2, 3); // "cde"
🧩 7. 清空和比較
s.clear(); // 清空字符串
s1 == s2 // 比較內容是否相等(重載了 ==)
s1.compare(s2); // 返回負數/0/正數
📌 四、string 的迭代器支持(像容器一樣)
for (char c : s) {std::cout << c;
}
也支持:
std::string::iterator it = s.begin();
while (it != s.end()) {std::cout << *it;++it;
}
📌 五、與 C 風格字符串互轉
🔁 string → C 字符串
const char* cstr = s.c_str(); // 返回 const char*
🔁 C 字符串 → string
char buf[] = "abc";
std::string s(buf);
📌 六、常見陷阱??
-
別忘記包含頭文件:
#include <string>
-
c_str()
返回的是const char*
,不能修改! -
at()
有越界檢查,[]
沒有。 -
substr(pos, len)
若超出范圍不會拋異常,而是只截取可用部分。
📌 七、小案例:單詞統計器
#include <iostream>
#include <string>int main() {std::string input;std::cout << "請輸入一句話:";std::getline(std::cin, input);int word_count = 0;bool in_word = false;for (char c : input) {if (!isspace(c)) {if (!in_word) {word_count++;in_word = true;}} else {in_word = false;}}std::cout << "單詞數:" << word_count << std::endl;return 0;
}
📌 八、string 底層原理簡述(進階)
- 實際上
std::string
是一個類,內部有一個動態分配的字符數組。 - C++11 起,大多數實現采用 Small String Optimization(SSO) —— 小字符串會直接存在對象內部,不會動態分配。
- 動態增長時,
std::string
會申請更大的內存空間并拷貝內容,策略類似于vector
。
? 九、string 相關常用函數速查表
操作 | 函數名 | 示例 |
---|---|---|
長度 | .size() | s.size() |
添加字符 | .push_back(c) | s.push_back('!') |
添加字符串 | .append(str) | s.append("abc") |
查找子串 | .find(str) | s.find("abc") |
替換子串 | .replace(p, l, r) | s.replace(2, 3, "hi") |
截取子串 | .substr(p, l) | s.substr(0, 3) |
清空 | .clear() | s.clear() |
比較字符串 | .compare(str) | s.compare("abc") |
轉C字符串 | .c_str() | printf("%s", s.c_str()) |
插入子串 | .insert(pos, s) | s.insert(2, "xx") |
刪除部分 | .erase(pos, len) | s.erase(0, 2) |
📚 十、推薦用法技巧
- 使用
std::getline()
獲取帶空格的整行輸入。 - 使用
+
運算符快速拼接多個字符串。 - 當性能關鍵時,盡量避免頻繁拼接小字符串(會頻繁分配內存)。
如果你感興趣,我還可以講:
std::string_view
的輕量引用方式- 多語言支持(Unicode處理)
ostringstream
結合string
輸出字符串std::format
(C++20)處理格式化字符串
需要我繼續擴展哪一部分嗎?比如底層實現、性能優化、string_view、高級技巧、源碼分析等,我都可以展開講。