首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言字符串處理函數完全指南:標準庫實現原理與安全用法

     編輯:關於C語言

核心字符串函數分類

1. 比較函數

int strcmp(const char *s1, const char *s2);       // 全比較,區分大小寫
int strncmp(const char *s1, const char *s2, size_t n); // 前 n 字符
int strcasecmp(const char *s1, const char *s2);   // 忽略大小寫(POSIX)
  • 返回值:<0 (s10 (s1>s2),值為首個不同字符 ASCII 差
  • 常用模式:if (!strcmp(s1, s2)) 判斷相等

2. 查找函數

char *strchr(const char *s, int c);      // 查字符,返回首次出現地址
char *strrchr(const char *s, int c);     // 最後一次出現
char *strstr(const char *haystack, const char *needle); // 查子串
char *strcasestr(const char *h, const char *n); // 忽略大小寫查子串

3. 複製函數

char *strcpy(char *restrict dst, const char *restrict src);      // 不安全
char *strncpy(char *dst, const char *src, size_t n);             // 指定長度
char *strdup(const char *s); // 自動 malloc 複製,需 free 釋放
  • strcpy 不檢查目標空間,**極易導致緩衝區溢出**
  • strncpy 若 src 長度 ≥ n,**不會自動添加結束符 '\0'**,需手動補齊
  • 推薦:snprintf(dst, size, "%s", src) 或 strlcpy(BSD)

4. 連接函數

char *strcat(char *restrict dst, const char *restrict src);      // 不安全
char *strncat(char *dst, const char *src, size_t n);             // 追加至多 n 字符
  • 同樣需確保目標空間足夠
  • 性能陷阱:strcat 每次需掃描 dst 尾部,循環連接呈 O(N²)

5. 長度與其他

size_t strlen(const char *s);           // 不含 '\0'
char *strtok(char *s, const char *delim); // 分割,破壞原串,非線程安全
char *strtok_r(char *s, const char *delim, char **saveptr); // 線程安全版
void *memcpy(void *dst, const void *src, size_t n); // 內存複製,不關心 '\0'
void *memmove(void *dst, const void *src, size_t n); // 重疊安全
int memcmp(const void *s1, const void *s2, size_t n); // 內存比較

手寫實現精華(教學用)

strcmp

int my_strcmp(const char *s1, const char *s2) {
    while (*s1 && *s1 == *s2) { s1++; s2++; }
    return *(const unsigned char *)s1 - *(const unsigned char *)s2;
}

strcpy

char *my_strcpy(char *dst, const char *src) {
    char *ret = dst;
    while ((*dst++ = *src++) != '\0');
    return ret;
}

strstr(暴力匹配)

char *my_strstr(const char *haystack, const char *needle) {
    size_t n = strlen(needle);
    if (n == 0) return (char *)haystack;
    for (; *haystack; haystack++)
        if (*haystack == *needle && !strncmp(haystack, needle, n))
            return (char *)haystack;
    return NULL;
}

安全編程準則

  1. **禁用** gets、strcpy、strcat、sprintf
  2. 使用帶長度限制版本:fgets、strncpy、strncat、snprintf
  3. 目標緩衝區大小傳遞給函數,內部嚴格檢查邊界
  4. 字符串操作前驗證指針非 NULL
  5. 涉及網絡/文件序列化時,顯式處理 '\0' 與長度前綴

現代替代方案

  • C11 附錄 K:strcpy_s、strcat_s、snprintf_s(需 __STDC_WANT_LIB_EXT1__)
  • 開源安全庫:SafeStr、Bstring、glib 字符串模組
  • C++ 直接用 std::string、std::string_view
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved