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

C 語言手寫字串庫實現 (String.c) 完整解析

     編輯:關於C語言

設計目標

在不使用 C++ std::string 或第三方庫的前提下,以純 C 實現一套具備動態記憶體管理、常用操作 (長度、複製、連接、比較、查找、分割、子串搜尋) 的字串抽象層。適合嵌入式環境、教學示範或需極小體積的專案。

核心資料結構與宏

[c]
typedef char* String;        // 字串即 char 指標
typedef int Status;          // 狀態碼
#define TRUE 1
#define FALSE 0
#define CHECK(t) do { if(!(t)) return 0; } while(0)  // 防衛性檢查宏

static String STRBUFFER = 0; // StrTok 內部靜態緩衝區

函數清單與實現細節

函數功能關鍵實現點
StrLen計算長度指標遞增遍歷至 \0,相減得長度
StrMake分配緩衝區malloc(len+1) 預留結尾空間
StrChr字元查找指定長度內查找首個匹配字元,返回指標
StrCat字串連接重新分配足夠空間,複製舊內容再附加新內容,更新目的指標
StrCmp字串比較逐字元比較,返回 1/0/-1 (大/等/小)
StrCpy字串複製呼叫 StrMake 分配目標空間再逐字元複製
StrFree釋放記憶體free(*str); *str = 0; 防野指標
StrPrint列印字串檢查非空後呼叫 puts
StrTok字串分割支援多字元分隔符集,內部靜態緩衝區保存狀態,類 strtok_r 行為
StrStr子串搜尋朴素演算法 (Naive),逐位置嘗試匹配

完整代碼

[c]
/* String.c */
#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
#define CHECK(t) do{if(!(t))return 0;}while(0)

typedef char* String;
typedef int Status;

static String STRBUFFER = 0;

int StrLen(String buf){
    String temp = buf;
    while(*temp++);
    return temp - buf - 1;
}

String StrMake(int length){
    return (String)malloc(length + 1);
}

String StrChr(String buf, char ch, int length){
    while(length-- && *buf++ != ch);
    return buf - 1;
}

void StrCat(String *dest, String src){
    String temp = (String)malloc(StrLen(*dest) + StrLen(src) + 1);
    String head = temp;
    String d = *dest;
    while(*d) *temp++ = *d++;
    while(*src) *temp++ = *src++;
    *temp = '\0';
    *dest = head;
}

int StrCmp(String buf1, String buf2){
    do{
        if(*buf1 > *buf2) return 1;
        if(*buf1 < *buf2) return -1;
        if(!*buf1) break;
        buf1++; buf2++;
    }while(1);
    return 0;
}

void StrCpy(String *dest, String src){
    *dest = StrMake(StrLen(src));
    String temp = *dest;
    while(*src) *temp++ = *src++;
    *temp = 0;
}

void StrFree(String *str){
    free(*str);
    *str = 0;
}

Status StrPrint(String str){
    CHECK(str);
    puts(str);
    return TRUE;
}

String StrTok(String dest, String src){
    if(dest) StrCpy(&STRBUFFER, dest);
    CHECK(src && STRBUFFER && *STRBUFFER);
    int length = StrLen(src);
    String ch = StrChr(src, *STRBUFFER, length);
    if(*ch == *STRBUFFER){
        do{
            *STRBUFFER++ = '\0';
            CHECK(*STRBUFFER);
            ch = StrChr(src, *STRBUFFER, length);
        }while(*ch == *STRBUFFER);
    }
    String result = STRBUFFER;
    String temp = result;
    while(*temp){
        ch = StrChr(src, *temp, length);
        if(*ch == *temp){
            *temp++ = '\0';
            CHECK(*temp);
            break;
        }else temp++;
    }
    STRBUFFER = temp;
    return result && *result ? result : 0;
}

String StrStr(String dest, String src){
    CHECK(dest && src && *dest && *src);
    do{
        String temp = src, rt = dest;
        while(*temp == *rt){ temp++; rt++; }
        if(!*temp) return dest;
        CHECK(*rt);
        dest++;
    }while(*dest);
    return 0;
}

使用範例

[c]
int main() {
    String s1 = 0, s2 = 0;
    StrCpy(&s1, "Hello");
    StrCpy(&s2, " World");
    StrCat(&s1, s2);        // s1 = "Hello World"
    StrPrint(s1);           // 輸出: Hello World
    
    String tok = StrTok("a,b;c", ",;"); // 分割
    while(tok) {
        printf("Token: %s\n", tok);
        tok = StrTok(0, ",;"); // 後續調用傳 0
    }
    StrFree(&s1); StrFree(&s2);
    return 0;
}

已知限制與改進方向

  • StrTok 非執行緒安全:靜態 STRBUFFER 導致不可重入,多執行緒環境需改為傳遞上下文結構體 (參考 strtok_r)。
  • StrStr 效率:朴素演算法最差 O(n*m),長文本建議換用 KMP 或 Boyer-Moore。
  • 記憶體錯誤處理:malloc 失敗未檢查,生產級代碼需補齊。
  • 編碼假設:假設單字節編碼 (ASCII/UTF-8 兼容),不支援寬字元。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved