2013-05-13 121 views
2

這是我的代碼,用於查找用戶在給定字符串中輸入的子字符串。在字符串中查找子字符串

bool find_str(char *str, char const *substr) { 
    while(*str) { 
     if(*str++ == *substr) { 
      char const *a = substr; 
      while((*str++ == *++a)); /*empty*/ 
      if(*a == '\0') 
       return true; 
     } 
    } 
    return false; 
} 
// If match found, then return true, else false 

int main(void) { 
    printf("%d", find_str("ABCDEF", "CDE")); /* Return true in this case */ 
    printf("%d", find_str("ABCDE", "CDE")); /* Return false in this case */ 

} 

正如註釋中所述,只要以附加字符結尾,就會返回true。如果不是,則返回false。我認爲增量/減量運算符存在問題。但我怎麼找不到?

+1

* str ++,* ++ a,讓我想到了試圖記住運算符優先級的難題。我不喜歡記憶的事情。請註釋它或添加一些括號()。 – John3136 2013-05-13 02:06:20

+0

在這裏它是如何工作的,首先它比較A和C,然後用B和C直到C == C,所以在嵌套的同時它會增加一個副作用使得D == D和E == E。(* + +第一個指向D,而* str ++也指向D,但在之後遞增) – 2013-05-13 02:07:38

+2

這不是代碼評論網站。無論如何,'strstr'這樣做 - 10秒google-foo,你可以找到實現,例如http://www.opensource.apple.com/source/xnu/xnu-792.13.8/libsa/strstr.c。在你的代碼中,有一些錯誤:爲了學習找到它們,我建議把類似'printf('''%s'=?='%s'\ n「,str,a)比較...你很快就會看到你真正的比較和意識到什麼是錯誤的,然後你可以推理和試驗來解決它。提示:正如蘋果所做的那樣,保持這種「匹配」的邏輯與「隨處查看」分開:「strncmp」。 – 2013-05-13 02:17:16

回答

4

這是因爲你的代碼決定停止在尋找\0只有後執行比較

*str++ == *++a 

這種情況將是true即使在比賽發生在對空終止字符串的結束,所以while循環將愉快地繼續超過兩個字符串通過空終止符,結果導致未定義的行爲。

更改狀態退出時*a爲零應該解決的問題:

while((*str++ == *++a) && (*a)); 
+0

感謝您的調試,它非常簡單 – 2013-05-13 02:11:04

+0

@ ashish2expert:作爲旁白(並且由@​​ John3136評論提示),我認爲稍微改變會讓大多數程序員更容易閱讀:'char const * a = substr + 1; while(* a &&(* str ++ == * a ++)){};' – 2013-05-13 02:57:01

1

我分析你的代碼一點點,根據我的分析, 我認爲這個問題是在這裏

 while((*str++ == *++a)); /*empty*/ 

也許你想添加另一份聲明中像下面

while((*str++ == *++a) && (*a != '\0')) ; /*empty*/ 

我猜你缺少一個空檢查,如果兩個指針指向什麼空終止他們仍然會向前走這正是發生了什麼

我要通過你的代碼,並發現了不少有趣的事情

  1. 比方說分配給CDE存儲器是在X
  2. 說再次分配用於ABCDEF存儲器是在X + 4(這是在我的機器的情況下)
  3. 說分配用於ABCDE存儲器塊是在一些X + Y或有什麼

現在當函數被第二次調用時 指針a和str指針都指向從X + 2開始的各個存儲單元,其中字符C滿足上述條件,但是即使條件達到了終點,條件仍然是true即在X + 3,因此A會向前移動並指向A,這會使您的程序錯誤地行爲