語法書 / AA 競程語法書 下冊 / 第八單元 / 字串函式庫 cstring(延伸知識)

8.8 字串函式庫 cstring(延伸知識)

C 字串的常用操作,<cstring> 函式庫都包好了。先看總表(完整清單在 cppreference):

函式 功能 注意
strlen(s) 回傳字串長度(到 '\0' 前為止的字元數) 效率陷阱見下方
strcpy(t, s) s 複製t(含 '\0' t 要夠大;方向是「後蓋前」
strcat(t, s) s t 的尾巴 t 要裝得下兩串合體
strcmp(s, t) 字典序比較(8.9 詳談) 回傳正/零/負,不是 1/0/−1
strncmp(s, t, n) 只比較前 n 個字元 同上
memset(s, c, n) s 的前 n位元組都填成 c 只適合字元陣列,見下方

strlen:長度=走到 '\0' 為止

#include <iostream>
#include <cstring>
using namespace std;

int main() {
    char s[20] = "abcde\0fgh";        // 故意在中間藏一個 '\0'
    cout << strlen(s) << '\n';        // 5:只數到第一個 '\0' 前
    return 0;
}

執行結果:

5

初始化明明給了 9 個字元、陣列開 20 格,strlen 卻回答 5——它從頭數到第一個 '\0' 就停,後面的 fgh 根本不算「字串的一部分」。再次印證:C 字串的一切以 '\0' 為準

strcpystrcat:複製與串接

字元陣列不能= 整串指派(t = s; 是編譯錯誤——陣列名稱不是變數),複製要用 strcpy

#include <iostream>
#include <cstring>
using namespace std;

int main() {
    char s[20] = "AACPSCHOOL";
    char t[20];
    strcpy(t, s);                  // 把 s 複製進 t(注意方向:後蓋前)
    cout << t << '\n';

    char u[40] = "I love ";
    strcat(u, s);                  // 把 s 接到 u 的尾巴
    cout << u << '\n';
    return 0;
}

執行結果:

AACPSCHOOL
I love AACPSCHOOL

memset:按位元組填充

memset(s, 'x', 5)s 的前 5 個位元組都填成 'x'。它填的單位是位元組,而 char 恰好一格一位元組——所以它是字元陣列的好朋友:

char s[10] = "abcdefg";
memset(s, 'x', 3);        // 前 3 格變 x
cout << s << '\n';        // xxxdefg

動手試試看:不用 strlen,自己寫一個 int myStrlen(char s[])(上冊 7.7 的陣列參數):從 s[0] 開始走,數到 '\0' 停。拿幾個字串跟內建 strlen 對答案。