2012-08-28 39 views
0

我遇到過這樣一個getword的例子。 我明白所有的檢查等,但我有ungetc的問題。瞭解ungetc在一個簡單的getword中使用

c確實滿足if ((!isalpha(c)) || c == EOF)並且也不能滿足while (isalnum(c)) - >它不是一個字母,也沒有一個數 - ungetc拒絕該char

假設它是'\n'

然後它到達return word然而它不能被返回,因爲它沒有保存在任何數組中。然後會發生什麼?

while (isalnum(c)) { 
     if (cur >= size) { 
      size += buf; 
      word = realloc(word, sizeof(char) * size); 

     } 
     word[cur] = c; 
     cur++; 
     c = fgetc(fp); 
    } 
    if ((!isalpha(c)) || c == EOF) { 
     ungetc(c, fp);   
    } 
    return word; 

編輯 @馬克拜爾斯 - 感謝,但c的拒絕是有目的的,而不會在一個無限循環一次又一次滿足條件?

+1

這是一個'getword'功能,而不是'getwordahdonemorecharacterww anyitmaybe''。它會讀取,直到遇到不是字母數字的字符。然後它將該角色放回流中並返回。大概它會返回一個字符指針,但是你省略了函數聲明,所以我不能100%確定。循環後的if語句中的'!isalpha(c)'等同於真,因爲字符永遠不會是字母的(如果是的話,循環就不會被破壞)。除非循環在錯誤處理過程中能夠中斷。 – Wug

回答

1

終端條件,就在您不理解的行之前,並不好。它可能應該是:

int c; 

... 

if (!isalpha(c) && c != EOF) 
    ungetc(c, fp); 

這意味着,如果最後一個字符閱讀是一個真正的字符(不是EOF),是不爲英文字母,由何體統採用輸入流fp它推回去重新處理。也就是說,假設你讀了一個空白;空白將終止循環,空白將被推回,以便下一個getc(fp)將再次讀取空白(如fscanf()fread()或對文件流fp的任何其他讀取操作)。如果不是空白的,你得到了EOF,那麼在我的修改後的代碼中沒有試圖推回EOF;在原始代碼中,EOF將被推回。

請注意,c必須是int而不是char

+0

我把它定義爲'int'。請參閱我的編輯,因爲在我看來,例如。 '\ n'會以無限循環結束。 –

+0

@PeterKowalski:爲什麼?在第一次迭代中,如果它讀取換行符作爲第一個字符,則循環終止,換行符被推回,單詞爲空,代碼(未顯示)處理代碼的非單詞部分(可能是代碼跳過空白?)將處理它。如果它是第二個或後續字符,則循環終止並且該單詞不爲空,則換行將換行以處理代碼的非單詞部分。請注意,我(不得不)假設代碼來讀取非單詞字符。 - 我從你的回答中看出你也是這樣做的。 –

1

ungetc將字符壓入流中,以便下一次讀取將再次返回該字符。

ungetc(c, fp); /* Push the character c onto the stream. */ 
/* ...etc... */ 
c = fgetc(fp); /* Reads the same value again. */ 

有時這可能是方便,如果你正在閱讀的文字,找出當前標記完成後,但尚未準備好讀下一個標記。

+0

謝謝,但你能看到我的編輯? –

+0

@PeterKowalski:你展示的代碼沒有無限循環。如果存在無限循環,那麼它可能是調用此函數的代碼中的一個錯誤。 –

+0

程序工作正常,我只是想象任何輸入,並在讀取它時調用過程。 –

0

好的。現在我明白爲什麼例如。 '\n'讓我感到困擾。我只是笨手笨腳的,忘記了main()中涉及到getword的部分。當然,在調用之前朗朗上口有一對夫婦的測試(另一個ungetc那裏),它fputs不是satisying字符isalnum 從這個是while環路getword總是與至少一個isalnum陽性,檢查在然後結束是開始浮現只適用於以下字符。