2017-10-28 73 views
-5

這是一個簡單的程序,用於檢查字符串是否是迴文。我在程序中編寫了以下代碼。輸出文件.exe沒有響應並停止工作C

program to check string is palindrome or not

當我編譯它,沒有錯誤,但是當我嘗試運行.exe文件,我總是得到以下信息。

.exe is not responding

+4

[不要將代碼和文本輸出爲圖像](https://meta.stackoverflow.com/q/303812/995714)。在這裏複製並粘貼它們 –

+1

如果'strlen(str)'爲0,那麼未定義的行爲....另外,[在任何情況下都不要使用'gets()'](https://stackoverflow.com/questions/1694036/why-是最被-IT-應該 - 不被使用的功能,如此危險,這一點)。這個危險的函數不再是C語言的一部分。 –

回答

0

根本這裏的問題是,循環退出條件不能得到滿足,這導致一個無限循環:

(i != j || i != j - 1) 

這種情況是邏輯上等同於:

!(i == j && i == j - 1) 

這顯然總是正確的,所以循環無限期地繼續。循環只需要繼續,只要j > i

這裏還有一個問題;即dangerous function gets() should never be used.此函數在C99中已棄用,並且已從C11中的語言中完全刪除。一種替代方法是使用fgets()。請注意,此函數保留換行符(如果緩衝區中有空間),所以您需要在獲取輸入後將其刪除。而且,如果緩衝區太小,字符可能會留在輸入流中。出於這個原因,最好宣佈一個慷慨大小的輸入緩衝區以降低此處出現問題的風險。沒有理由不使用一個包含1000個字符的輸入緩衝區,而我通常只用4096來表示這樣的事情。內存很便宜。

此外,在發佈的代碼中存在未定義行爲的風險,因爲輸入字符串可能爲空。在這種情況下,strlen(str)將爲0,因此在循環主體j的第一次執行中將遞減爲-1。但數組訪問str[-1]超出範圍,並導致未定義的行爲。

此問題可以通過檢查j在第一次遞減前爲正值來解決。請注意0​​是數組索引的正確類型,因爲它是一個unsigned整數類型,保證能夠保存任何數組索引。另請注意,strlen()函數返回的值爲size_t,而不是int

以下是發佈代碼的修改版本。 size_t類型用於數組索引。輸入字符串的長度存儲在j中,然後只有當它是正值時纔會遞減;這將j設置爲空終止符前面的字符的索引,只要輸入字符串不是空字符串即可。循環繼續,而j大於i,並且由這些值索引的字符相匹配。循環結束後,str[i]str[j]應該同意;如果他們不這樣做,那麼投入就不是迴文。

#include <stdio.h> 
#include <string.h> 

#define BUF_SZ 4096 

int main(void) 
{ 
    char str[BUF_SZ]; 

    printf("Enter string:\n"); 
    fgets(str, sizeof str, stdin);   // Never use gets() 
    str[strcspn(str, "\r\n")] = '\0';  // remove '\n' 

    size_t i = 0; 
    size_t j = strlen(str); 
    if (j > 0) { 
     --j; 
    } 

    while (i < j && str[i] == str[j]) { 
     ++i; 
     --j; 
    } 

    if (str[i] == str[j]) { 
     puts("string is palindrome!!"); 
    } else { 
     puts("string is not palindrome!!"); 
    } 

    return 0; 
}