在 C 語言學習中,手寫 mystrstr 函數查找子字串是常見練習。有初學者發現自寫函數總返回「沒有找到」,即使明明存在匹配。經排查,問題出在標誌變數 flag 的重置邏輯上。
char *mystrstr(char *string, char *findstring) {
if (string == NULL || findstring == NULL) return NULL;
int flag = 1;
while (*string != '\0') {
char *p = string;
char *px = string;
char *now = findstring;
while (*now != '\0') {
if (*px == *now) {
px++; now++;
} else {
flag = 0; break;
}
}
if (flag == 1) return p;
string++;
}
return NULL;
}
上述代碼在內層 while 結束後,若匹配成功,flag 仍為 1,可正常返回;但若中途不匹配導致 flag=0,外層循環繼續時 flag 不會重置為 1,導致後續即使匹配也無法進入 if (flag==1)。
在內層循環結束前,需根據 *now 是否為 '\0' 重置 flag:
while (*now != '\0') {
if (*px == *now) { px++; now++; }
else { flag = 0; break; }
if (*now != '\0') flag = 1; // 關鍵:匹配未結束時重置 flag
}
這樣每次外層循環嘗試新起始位置時,flag 都能正確反映本輪匹配狀態。
#include <stdio.h>
#include <string.h>
char *mystrstr(char *string, char *findstring) {
if (string == NULL || findstring == NULL) return NULL;
int flag = 1;
while (*string != '\0') {
char *p = string;
char *px = string;
char *now = findstring;
while (*now != '\0') {
if (*px == *now) { px++; now++; }
else { flag = 0; break; }
if (*now != '\0') flag = 1;
}
if (flag == 1) return p;
string++;
}
return NULL;
}
int main() {
char str1[20] = "i love you";
char str2[20] = "love";
char *p = mystrstr(str1, str2);
if (p == NULL) printf("沒有找到\n");
else printf("找到:%s\n", p);
return 0;
}
編寫字串匹配演算法時,狀態變數的初始化與重置至關重要。建議採用更清晰的雙指針或 KMP 算法提升效率與可讀性。