2017-06-14 350 views
-1

我正在使用Xcode 8學習C,編譯器在執行while或for循環後不運行任何代碼。這是一個錯誤?我該如何解決它?執行while或for循環後沒有代碼執行C

在下面printf("code executed after while-loop");提供的例子中從未執行

#include <stdio.h> 

int getTheLine(char string[]); 

int getTheLine(char string[]) { 

    char character; 
    int index; 
    index = 0; 

    while ((character = getchar()) >= EOF) { 

    string[index] = character; 
    ++index; 
    } 

    printf("code executed after while-loop"); 
    return index; 
} 

int main(int argc, const char * argv[]) { 

    char string[100]; 
    int length = getTheLine(string); 
    printf("length %d\n", length); 

    return 0; 
} 
+0

您可以開始向我們展示您的代碼。 –

+2

編譯器不應該運行任何代碼。它應該將[*翻譯單元*](https://en.wikipedia.org/wiki/Translation_unit_(programming))編譯成目標文件,然後將其鏈接到可執行文件中。 IDE然後可以啓動一個進程來運行可執行文件。 –

+1

更重要的是,請[閱讀關於如何提出好問題](http://stackoverflow.com/help/how-to-ask)並學習如何創建[最小,完整和可驗證示例](http ://stackoverflow.com/help/mcve)。 –

回答

2

getchar返回int不是char,和比較EOF應與!=操作者而不是操作者>=來完成。

... 
int character; // int instead of char 
int index; 
index = 0; 

while ((character = getchar()) != EOF) { // != instead of >= 
... 
+0

我最初編寫了像你所建議的代碼。同樣的問題 –

+1

@CristianLăpuşan你的代碼與我的修復應用程序在這裏工作很好。你的輸入是什麼?你的平臺是什麼?請記住:在Linux上,EOF使用Ctrl + D完成,在Windows上使用Ctrl + Z完成。 –

+0

我正在使用Xcode,macOS Sierra。 –

2

這是>= EOF,這將讓病情始終true。其原因是,getchar()「有效」的結果將是一個正整數,和一個「非有效」導致像文件結束-將EOF,其是負(參見getchar()):

EOF ... int類型和負值

因此的整數常量表達式,從getchar任何有效的結果將是>EOF,而結束文件的結果將是==EOF,使得>= EOF將總是匹配。

改爲寫!= EOF

此外,值得注意的是你不串終止字符'\0',使得在​​使用string像一個字符串(例如,將產生不確定的行爲(崩潰或別的東西,可能不需要)終止您的字符串。 所以寫至少:

while ((character = getchar()) != EOF) { 
    string[index] = character; 
    ++index; 
} 
string[index]='\0'; 

然後還有,你可以寫出界,例如如果一個人在你的例子進入100多個字符,但檢查這現在是超出了實際問題,這是對的問題。無限循環

+0

如果我提前退出函數,說我在循環後立即插入「if(character == 47){return index;}」,那麼代碼運行正常 –

+0

@CristianLăpuşan:我想你的意思是「內循環」,因爲你的循環永遠不會結束;所以「while循環後執行的代碼」永遠不會被打印,對吧? –

2

符號常數EOF整數常數,類型爲int。它(通常)被定義爲一個宏,如-1

的問題是,作爲(32位)的值-1int具有值0xffffffff和作爲(8位)char相同的值將是0xff。這兩個值不相等。這反過來意味着你的循環條件將永不爲假,導致無限循環。

解決此問題的方法是,所有讀取字符的標準函數都將其作爲int返回。這意味着您的變量character也需要具有該類型。

重要注意事項:如果普通char是有符號或無符號類型,這是一個編譯器實現細節。如果它是有符號的,那麼與int的比較將導致符號擴展char值在比較中被提升時。這意味着signed char與值0xff將擴展到int0xffffffff。這意味着如果char已簽名,那麼比較就會起作用。

這意味着您的編譯有charunsigned char。所以推廣到intunsigned char0xff將爲0x000000ff


至於爲什麼-1變得0xffffffff是因爲如何負數的計算機上通常表示,其中一種叫two's complement


您的代碼中還有另外兩個缺陷。

首先是因爲循環是無限的,你會去方式string陣列的界限,導致未定義行爲(以及可能的崩潰遲早)。解決方法是添加一個條件,以確保index永遠不會達到100(在數組的特定情況下,應該真正作爲參數傳遞)。

第二個問題是,如果你打算用string數組作爲實際字符串,你需要終止它。 C中的字符串實際上被稱爲null 終止字符串。該終結符是字符'\0'(等於整數0),並且需要放在每個要傳遞給處理此類字符串的標準函數的字符串的末尾。擁有這個終結符意味着一個100字符數組只能有99個字符,以便能夠匹配終結符。這對解決上述問題具有影響。至於如何添加終止符,只需在循環後執行string[index] = '\0';(如果index在當然範圍內)。

+0

它不工作.. –

+1

@CristianLăpuşan* *什麼*「不工作」?你是否將'character'的類型改爲'int'?你在做別的事情嗎?你是否嘗試過在調試器中的代碼?你試過在循環後面添加一個(尾隨)換行符到你打印的字符串(因爲輸出到'stdout'是默認的行緩衝)? –

+0

Upvoted爲你帶來的所有細節。但只是爲了理解:在((char)-1 ==(int)-1'中不會整體提升)確保'(char)-1'實際上是擴展的到'0xffffffff'? –