2012-08-24 20 views
2

我的問題很簡單:「爲什麼我的第10和11行代碼無法正常工作?」我的代碼的預期目的是完全按照原始的K & R代碼的意圖執行,但是不論何時(getchar()=='\ n')都不計算nc,您能否給我提供啓發?C編程 - K&R示例1.5.2 - 修改後的程序無法按預期運行[解決]

略微改進的K & R代碼裏面:

/** K&R - 1.5.2 Character Counting **/ 
#include <stdio.h> 

/* count characters in input; 1st version */ 
main(){ 
    long nc; 

    nc = 0; 
    while (getchar() != EOF){ 
    if (getchar() != '\n'){ 
     ++nc; 
    } 
    } 
    printf("%ld\n", nc); 
} 

我使用64位Windows 7,CodeBlocks10.05,GNU GCC編譯器。

我目前的進展和認識:

在樣品上來看,我的字two鍵入並回車,相當於4個輸入,在這之後我按CTRL + Z在^Z或EOF字符輸入。該程序然後打印1。我期待它打印3。我想唯一合乎邏輯的解釋是,它與我的意圖完全相反(只有計算換行符?)。事實證明,如果我輸入單詞two並按下回車鍵,讓我們說4次,它會打印4。對於輸入的每一個換行符,似乎都計數爲nc,但是如果我單獨按下輸入(在這種情況下是4次)然後輸入EOF,它總是會輸出0。經過進一步的實驗,通過一些看不見的東西4也許是這個計劃的一個神奇數字。如果我啓動它並準確地按下確定鍵(一個可以被4整除的數字)然後EOF它會打印0。但是,如果我輸入一些其他次數的EOF什麼也不做,並且我必須一個接一個地輸入^Z兩行,以正確結束while循環,並且它打印1。這讓我難以置信!

回答

6

問題在於,您需要將getchar()的值保存在int中 - 因爲每次增加計數時都會讀取兩個字符。其中之一是在EOF測試中;第二個是在換行測試中。

int c; 

while ((c = getchar()) != EOF) 
{ 
    if (c != '\n') 
     ++nc; 
} 

你需要的getchar()結果存儲在一個int,而不是一個char的原因是,它可以返回每一個可能的char價值,也具備獨到的價值,EOF。如果你不使用int(你直接存儲到一個char),兩件事情將會發生:

  1. 如果char是有符號類型,合法的字符(通常Y-元音變音,Y,拉丁小字母Y WITH DIAERESIS,U + 00FF - 至少在源自Latin 1或ISO 8859-1的代碼集中)將被解釋爲等同於EOF,並且程序將提前終止。
  2. 如果char是一個無符號類型,那麼沒有任何字符會等同於EOF,所以程序永遠不會停止循環。

這些情況都不可取。將getchar()的返回值存儲在int中可防止這兩個問題;這是'唯一'(或者至少是最簡單的)正確的方法。

+0

附近放置括號謝謝你對char類型的傑出解釋 –

3
int c; 

[...] 

while ((c = getchar()) != EOF) { 
    if (c != '\n') { 
     ++nc; 
    } 
} 

每次通話時間getchar()要從stdin消耗字符。

+2

你應該解釋爲什麼你的解決方案是正確的,只是一點點。 –

+0

哇,我剛剛寫完了,除了我做了一個字符變量c,它和原來的K&R代碼做了同樣的事情? –

+0

@pyingSaucepan'char'不夠寬以容納'EOF',這就是爲什麼'getchar'返回'int'的原因。 –

5

簡而言之,你打電話getchar()兩次,所以你在每次迭代中消耗兩個字符。

你應該明白,調用getchar()從輸入流中讀取一個字符。如果你想測試一個換行符,你應該將該字符存儲在一個變量中,然後測試該變量。