在不使用 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;
}
STRBUFFER 導致不可重入,多執行緒環境需改為傳遞上下文結構體 (參考 strtok_r)。malloc 失敗未檢查,生產級代碼需補齊。