【C++ 筆記】C++ 與 C style string
【C++ 筆記】C++ 與 C style string
C-style string
先從老祖宗 C 語言講起好了。
C-style string 就是字元陣列所組成的,最後結尾用 null(\0)表示字串結束。
如:
1 | char a[] = "Hello"; // 等於 char a[] = {'H', 'e', 'l', 'l', 'o', '\0'}; |
這種字元陣列需要搭配 <cstring> 標頭檔引入 C 語言版本的字串函式庫。
裡面常見的操作如下:
| 函式名 | 功能 |
|---|---|
strlen(s) | 回傳字串長度(不含 \0) |
strcpy(dst, src) | 字串複製 |
strcmp(s1, s2) | 字串比較(回傳 0 相同,非 0 不同) |
strcat(dst, src) | 字串串接 |
dst 就是 destination,意為目的地;src 就是 source,意為來源。
strcpy(dst, src) 就是將 src 複製到 dst。
strcat(dst, src) 就是將 src 串接於 dst 上。
範例:
1 |
|
Output:
1 | str1 after strcpy: Hello |
Strength and weakness
優點:
- 效能高,無額外抽象(Abstract)。
- 與低階記憶體操作無縫整合。
- 在嵌入式系統、C 接口中常見。
缺點:
- 安全性低,常因未妥善管理記憶體導致緩衝區溢位(buffer overflow)。
- 很麻煩,沒有 C++ style string 來的方便。
- 無法支援動態擴充長度,一個字串一旦寫好就固定長度了。
C++ style string
C++ style string 是由類別所構成的,使用前須引入標頭檔 <string>。
要建立一個字串,如下:
1 |
|
可以用中括號存取某個字元,索引(位置)起始值一樣從 0 開始,如上範例的 name[0] 就會取得 'L' 字元。
1 |
|
Output:
1 | L |
另外 C++ style string 是可以更新字串的,不像 C-style string 那麼死板:
1 |
|
Output:
1 | 王奕翔醜男 |
也可以更改特定字元:
1 |
|
Output:
1 | LikeTseng |
相關函式
| Function | Description |
|---|---|
length() | 回傳字串長度。 |
swap(a, b) | 交換兩個字串。 |
size() | 查找字串的大小。 |
resize() | 將字串長度調整為給定的字元數。 |
find() | 尋找傳入參數的字串。 |
push_back(c) | 把字元 c 推送到字串的結尾。 |
pop_back(c) | 移除字串中最後一個字元 c。 |
clear() | 清空字串。 |
strncmp(const char *str1, const char *str2, size_t count) | 最多比較兩個字串的前 num 個位元組。 |
strncpy(char *dest, const char *src, size_t n) | 該函式與 strcpy() 函式類似,不同之處在於最多複製 src 的 n 個位元組。 |
strrchr(char* str, int chr) | 定位字串中某個字元的最後出現的位置。 |
strcat(dest, src) | 把來源字串 src 的副本附加到目標字串 dest 的結尾。 |
replace() | 把區間 [first,last) 中每個等於舊值的元素替換為新值。 |
substr() | 從給定字串中建立子字串。 |
compare() | 比較兩字串並以整數形式回傳結果。 |
erase() | 刪除字串的某個部分。 |
rfind() | 查找字串最後一次出現的位置。 |
表格來源:https://www.geeksforgeeks.org/strings-in-cpp/
find() 有多種語法:
1 | s.find(sub, pos); // For substring 用於子字串 |
以上的第二種語法僅適用於 C-style string。
find() 範例:
1 |
|
Output:
1 | "fox" found at position: 16 |
string::npos 代表找不到字串,回傳值的型態為 size_t,通常為其型態的最大值 4294967295。
接下來是有關 strncmp(), strncpy(), strrchr(), strcat() 的範例:
strncmp()
strncmp() 回傳值:0(相等)、<0(str1 < str2)、>0(str1 > str2)
1 |
|
Output:
1 | 前 3 個字元相同 |
strncpy(dest, src, n)
若 src 長度小於 n,dest 會補上 \0。
若 src 長度大於或等於 n,可能不會自動補 \0,需手動處理。
1 |
|
Output:
1 | 複製後的 dest: Hello |
strrchr(str, ch)
strrchr(str, ch)回傳指向ch最後一次出現位置的指標,找不到回傳nullptr。- 可用指標運算計算該位置。
1 |
|
Output:
1 | 最後一個 's' 出現在位置: 17 |
strcat(dest, src)
strcat(dest, src):將src字串加到dest字串尾端。dest必須有足夠的空間存放合併後的結果,否則會產生記憶體區段(Segmentation fault)錯誤。
1 |
|
Output:
1 | 連接後的字串: Hello, world! |
以下是有關函式 replace(), substr(), compare(), erase(), rfind() 的範例:
replace(pos, len, new_str)
str.replace(pos, len, new_str):從位置pos開始,取代長度為len的部分為new_str。
1 |
|
Output:
1 | 替換後字串: I love oranges |
substr(pos, len)
substr(pos, len):從pos開始擷取長度為len的子字串。- 若省略
len,則取到字串尾端。
1 |
|
Output:
1 | 擷取的子字串: world |
a.compare(b)
a.compare(b):- 回傳 0:a 與 b 相同
- 回傳 <0:a 小於 b(字典序)
- 回傳 >0:a 大於 b。
可用來實作排序(自訂排序)或搜尋。
1 |
|
Output:
1 | a < b |
erase(pos, len)
erase(pos, len):從pos開始,刪除len個字元。- 也可用
erase(iterator)或erase(iterator_first, iterator_last)。
1 |
|
Output:
1 | 刪除後字串: 012789 |
rfind(substring)
- rfind(substring):回傳子字串最後一次出現的位置。
- 若找不到,則回傳
string::npos。
1 |
|
Output:
1 | "two" 最後一次出現於位置: 14 |
總結
C-style string
C-style string 是由 C 語言時期所沿用至今的字串表示方式,形式為字元陣列,並以特殊終止字元 '\0'(null character)表示字串結尾。
1 | char a[] = "Hello"; // 等價於 {'H', 'e', 'l', 'l', 'o', '\0'} |
常見的函式
在 C++ 使用時用 <cstring> 標頭檔引入。
| 函式 | 說明 |
|---|---|
strlen(s) | 傳回字串長度(不包含 \0) |
strcpy(dst, src) | 將 src 字串複製到 dst |
strcmp(s1, s2) | 比較兩個字串(相同回傳 0) |
strcat(dst, src) | 將 src 串接於 dst 之後 |
- dst(destination):目標字串(目的地)。
- src(source):來源字串。
優點:
- 效能高,無額外抽象(Abstract)。
- 與低階記憶體操作無縫整合。
- 在嵌入式系統、C 接口中常見。
缺點:
- 安全性低,常因未妥善管理記憶體導致緩衝區溢位(buffer overflow)。
- 很麻煩,沒有 C++ style string 來的方便。
- 無法支援動態擴充長度,一個字串一旦寫好就固定長度了。
C++ style string
C++ style string 是以 std::string 類別為核心的字串型態,需引入 <string> 標頭檔。
用起來比 C-style string 更方便,也更符合現代化。
範例:
1 |
|
也可以更新字串:name = "abc";。
也能更新特定字元:name[1] = 'i';。
常見函式表
| Function | Description |
|---|---|
length() | 回傳字串長度。 |
swap(a, b) | 交換兩個字串。 |
size() | 查找字串的大小。 |
resize() | 將字串長度調整為給定的字元數。 |
find() | 尋找傳入參數的字串。 |
push_back(c) | 把字元 c 推送到字串的結尾。 |
pop_back(c) | 移除字串中最後一個字元 c。 |
clear() | 清空字串。 |
strncmp(const char *str1, const char *str2, size_t count) | 最多比較兩個字串的前 num 個位元組。 |
strncpy(char *dest, const char *src, size_t n) | 該函式與 strcpy() 函式類似,不同之處在於最多複製 src 的 n 個位元組。 |
strrchr(char* str, int chr) | 定位字串中某個字元的最後出現的位置。 |
strcat(dest, src) | 把來源字串 src 的副本附加到目標字串 dest 的結尾。 |
replace() | 把區間 [first,last) 中每個等於舊值的元素替換為新值。 |
substr() | 從給定字串中建立子字串。 |
compare() | 比較兩字串並以整數形式回傳結果。 |
erase() | 刪除字串的某個部分。 |
rfind() | 查找字串最後一次出現的位置。 |
表格來源:https://www.geeksforgeeks.org/strings-in-cpp/
find() 有多種語法:
1 | s.find(sub, pos); // For substring 用於子字串 |
以上的第二種語法僅適用於 C-style string。
strncmp(), strncpy(), strrchr(), strcat() 總表
| 函式名稱 | 功能說明 |
|---|---|
strncmp() | 比較兩字串前 n 個字元 |
strncpy() | 複製字串前 n 個字元到另一字串 |
strrchr() | 找到某字元最後一次出現位置 |
strcat() | 將一字串接到另一字串之後 |
replace(), substr(), compare(), erase(), rfind() 總表
| 函式 | 功能說明 |
|---|---|
replace() | 替換字串中的某段子字串 |
substr() | 擷取子字串 |
compare() | 比較兩字串字典順序 |
erase() | 刪除某段字串 |
rfind() | 搜尋某子字串最後一次出現的位置 |


