2010-10-19 119 views
2

我有這個任務來實現strcmp函數。有時它運行正常,但有時會崩潰。請幫幫我。C++程序崩潰

#include <iostream> 

using namespace std;  

int mystrcmp(const char *s1, const char *s2); 

int main() 
{ 
cout<<mystrcmp("A","A")<<endl;  
cout<<mystrcmp("B","A")<<endl;  
cout<<mystrcmp("A","B")<<endl;  
cout<<mystrcmp("AB","A")<<endl; 

return 0;  
} 

int mystrcmp(const char *s1, const char *s2) 
{ 
while (*s1==*s2) 
{ 
    s1++; 
    s2++; 
} 

if(*s1=='\0') 
    return(0); 

return(*s1-*s2); 
} 
+0

這就是問題所在?它包括字符串終止檢查,所以它不應該崩潰。 //如果通過編輯修改了代碼,那麼如果這個問題沒有被評論標記,那麼問題就沒有了。 – harper 2010-10-19 05:42:00

回答

10

如果兩個輸入是相同的,因爲你的循環將繼續超越終止nul字符就會死機。

while (*s1==*s2) { 

    // if s1 points to nul character, then s2 should also, because of the == 
    // which means we've reached the end of the strings and they are equal 
    // so return 0. 
    if(*s1=='\0') 
    return 0; 

    s1++; 
    s2++; 
} 

return *s1-*s2; 
+0

謝謝你!它現在完美。我欠你一杯啤酒:) – John 2010-10-19 04:34:52

+2

在這裏所以你給啤酒給予upvote :) – codaddict 2010-10-19 04:41:07

+0

擴大codaddict的評論。指向一個字符串的末尾(即,超過'\ 0'的字符串)是合法的。解引用它不是。 John的原始while循環可能被單獨留下,並捕獲所有四個可能的post-loop案例。 (不要考慮這一點,除非每次通過循環的if()由於某種原因而昂貴)。 – 2010-10-19 05:01:21

3

mystrcmp會高興地跑出字符串的結尾,因爲你的NUL終止測試外循環。如果字符串相同,則*s1*s2都爲0,並且循環繼續。

3
while (*s1==*s2) 
{ 
s1++; 
s2++; 
} 

'\ 0' == '\ 0'

1

你需要考慮會發生什麼,如果你的兩個字符串如下:

爲了解決這個問題,你必須爲nul字符檢查內部循環

s1:this is a string\0|abcdef 
s2:this is a string\0|abcdef 
     good memory <-|-> bad memory 

因爲你只是在內容相同時推進指針,你可能會以未定義的方式讀取內存。

更好的方法是立足你下面的僞代碼的代碼:

def strcmp(s1,s2): 
    while character at s1 is not '\0': 
     if character at s1 is not the same as character at s2: 
      exit while loop 
     increment s1 and s2 
    return difference between *s1 and *s2 

這將停止當你要麼到達第一個字符串的結尾或者你發現一個差異(包括如果您在第一個字符串之前已經達到了第二個字符串的末尾)。