字符串與內存操作是 C 語言基礎且高頻的編程任務。本文系統整理 <string.h> 及 <memory.h> 中所有核心函數,按功能分類,提供**標準原型、語義說明、參數含義、返回值、所需頭文件、可編譯範例**,作為離線速查字典。
| 函數 | 原型 | 核心差異 | 示例 |
|---|---|---|---|
strcpy | char* strcpy(char* dest, const char* src) | 複製含 \0 的完整字符串,無長度檢查 (危險) | strcpy(buf, "hello") |
strncpy | char* strncpy(char* dest, const char* src, size_t n) | 複製 n 字符,**不保證以 \0 結尾** (需手動補) | strncpy(buf, src, 3); buf[3]='\0'; |
strdup | char* strdup(const char* s) | 自動分配內存 並複製,**調用者須 free** (POSIX, 非 C89 標準) | char* p = strdup(s); free(p); |
memcpy | void* memcpy(void* dest, const void* src, size_t n) | 內存塊複製,**不處理 \0**,允許任意二進制數據,**源目不重疊** | memcpy(dst, src, sizeof(struct)) |
memmove | void* memmove(void* dest, const void* src, size_t n) | **安全處理重疊** 內存區域 (內部判斷方向複製) | memmove(buf+1, buf, 10) |
memccpy | void* memccpy(void* dest, const void* src, int c, size_t n) | 複製至遇到字符 c 或滿 n 字節,**返回 c 後位置指針** | memccpy(dst, src, '\n', 100) |
| 函數 | 原型 | 說明 |
|---|---|---|
strcat | char* strcat(char* dest, const char* src) | 追加 src 到 dest 末尾 (覆蓋 \0),無長度檢查 |
strncat | char* strncat(char* dest, const char* src, size_t n) | 追加 src 前 n 字符,保證 \0 結尾 |
memset | void* memset(void* s, int c, size_t n) | 將 s 前 n 字節置為 c (按 unsigned char 取值) |
strset | char* strset(char* s, int c) | 將字符串所有字符置為 c (Microsoft 擴展) |
strnset | char* strnset(char* s, int c, size_t n) | 將字符串前 n 字符置為 c (Microsoft 擴展) |
| 函數 | 原型 | 返回值 / 語義 |
|---|---|---|
strcmp | int strcmp(const char* s1, const char* s2) | 字典序比較:< 0 / = 0 / > 0 |
strncmp | int strncmp(const char* s1, const char* s2, size_t n) | 比較前 n 字符 |
memcmp | int memcmp(const void* s1, const void* s2, size_t n) | 二進制比較前 n 字節 |
memicmp | int memicmp(const void* s1, const void* s2, size_t n) | 忽略大小寫 比較前 n 字節 (擴展) |
strchr | char* strchr(const char* s, int c) | 查找字符 c **首次** 出現位置 |
strrchr | char* strrchr(const char* s, int c) | 查找字符 c **最後** 出現位置 |
strstr | char* strstr(const char* s1, const char* s2) | 查找子串 s2 在 s1 中首次出現位置 |
strpbrk | char* strpbrk(const char* s1, const char* s2) | 查找 s1 中**首個** 屬於 s2 字符集的字符 |
strcspn | size_t strcspn(const char* s1, const char* s2) | 返回 s1 開頭**不包含** s2 任何字符的最大長度 |
strspn | size_t strspn(const char* s1, const char* s2) | 返回 s1 開頭**僅包含** s2 字符的最大長度 |
memchr | void* memchr(const void* s, int c, size_t n) | 在 s 前 n 字節中查找字符 c |
| 函數 | 原型 | 說明 |
|---|---|---|
strlen | size_t strlen(const char* s) | 返回字符串長度 (不含 \0) |
strrev | char* strrev(char* s) | 原地反轉字符串 (Microsoft 擴展) |
strupr | char* strupr(char* s) | 轉大寫 (Microsoft 擴展) |
strlwr | char* strlwr(char* s) | 轉小寫 (Microsoft 擴展) |
strtok | char* strtok(char* s1, const char* s2) | 按 s2 分隔符分解 s1,**破壞原串**,非線程安全 (用 strtok_s/strtok_r) |
strerror | char* strerror(int errnum) | 將錯誤碼轉為可讀字符串 (配合 errno) |
strcpy, strcat, sprintf, gets, strtok — 緩衝區溢出高危。strcpy_s / strcat_s / sprintf_s (MSVC / C11)strncpy_s / strncat_s (帶長度檢查)strtok_s (線程安全,保存上下文指針)snprintf (標準 C99,跨平台安全格式化)std::string, std::string_view, std::format (C++20), std::span (C++20) — 從源頭消除裸指針風險。strncpy 不自動補 \0 → dest[n] = '\0';strtok 修改原字符串、非線程安全、分隔符為字符**集合**而非子串。memcpy 處理重疊行為未定義 → 改用 memmove。strcmp 返回值僅表示正負零,**不可假設為 -1/0/1**。strlen 返回 size_t (無符號),與有符號數比較警惕隱式轉換陷阱。