2017-07-21 33 views
-1

我用K & R. 現在的功能代碼「getint()」到「C程序設計書」走出如下: - >getchar()函數是否有自己的緩衝區來存儲剩餘的輸入?

#include<stdio.h> 

#define BUFSIZE 100 

char buf[BUFSIZE]; 
int bufp = 0; 

int getch(void) { 
    return (bufp > 0)?buf[--bufp]:getchar(); 
} 

void ungetch(int c) { 
    if(bufp >= BUFSIZE) 
     printf("ungetch: too many characters\n"); 
    else 
     buf[bufp++] = c; 
} 

int getint(int *pn) { 
    int c, sign; 

    while(isspace(c = getch())); 

    if(!isdigit(c) && c != EOF && c != '-' && c != '+') { 
     ungetch(c); 
     return 0; 
    } 

    sign = (c == '-')?-1:1; 
    if(c == '+' || c == '-') 
     c = getch(); 

    *pn = 0; 
    while(isdigit(c)) { 
     *pn = (*pn * 10) + (c - '0'); 
     c = getch(); 
    } 

    *pn *= sign; 

    if(c != EOF) 
     ungetch(c); 


    return c; 
} 


int main(int argc, char** argv) { 

    int r, i; 

    while((r = getint(&i)) != EOF) 
     if(r != 0) 
      printf("res: %d\n", i); 

    return 0; 
} 

現在我沒有得到即使我試圖在紙上理論上運行它,但這個功能一步一步的執行。

而我輸入「23」的事實。它如何轉換爲23,我知道有邏輯將「23」轉換爲23,但c = getch()不會在輸入後將其餘的「3」存儲在緩衝區中,然後如何返回3,在轉換。 getchar()是否有自己的緩衝區,它存儲所有inout字符並將它們取1。 任何幫助都非常有用。

+0

Getch捕獲每個輸入鍵盤並將其存儲在緩衝區中 – VIX

+0

'getchar()'就像'getc(stdin)','stdin'是'stdio.h'中的默認'FILE *'。這些都是緩衝的。 –

+3

我們不是一個輔導網站。也許你跳過了一些章節,或者應該讀一些其他書。 K&R期望一些基本的Unix /計算基礎知識。自18年以來,它對於C語言也是過時的。獲取一本涵蓋現代C11(至少C99)的書。代碼片段中的 – Olaf

回答

1

中的代碼片斷你提供的,主邏輯是在這裏:

1. *pn = 0; 
2. while(isdigit(c)) { 
3.  *pn = (*pn * 10) + (c - '0'); 
4.  c = getch(); 
5. } 

pn是將容納整數和c的最終值的緩衝液是受每次讀取,一個炭一個,由getchar()。所以,當你正在閱讀的「23」,這裏發生了什麼:

  1. '2'被讀取到c
  2. pn = 0; c = '2';第3行(從主邏輯片斷),我們乘10的值緩衝區,並添加(0x32 - 0x30
  3. pn = 2; c = 2;
  4. 閱讀'3'c
  5. 乘以pn通過10給你20,您可以添加(0x33 - 0x30),你有最後的23

事情要記住:

  • getchar()讀取字符一個接一個從標準
  • 添加簡單printf()報表會幫助你在理解你的程序流程
  • 嘗試在gdb下運行它,檢查變量的值
1

而且我輸入「23」的事實。它如何轉換爲23,我知道有邏輯將「23」轉換爲23,但c = getch()不會在輸入後將其餘的「3」存儲在緩衝區中,然後如何返回3,在轉換。確實的getchar()有它自己的緩衝區,它存儲所有INOUT字符和1

從這獲取它們1,我讀了你期望getch()以某種方式得到你的整個輸入線。那麼,那是錯誤的。

首先關於這個getchar() vs getch()混淆的快速旁註。在標準 C,getch()需要FILE *類型的論據。這是一個getchar()相當於getch(stdin)。這裏顯示的代碼似乎是預標準C.我假設getch()的任何發生應該真的是getchar()

你必須知道的是,stdio.hFILE *被緩衝。有不同的模式(無緩衝,行緩衝和完全緩衝)。

stdin是您的默認輸入流。它通常來自鍵盤(但你的程序不關心它,它可以被重定向到來自文件,管道等)。 stdin的默認緩衝模式是行緩衝。當你輸入23 <enter>是,2只會在輸入緩衝區去的stdin,還有3和一個換行符如下只有當(按下回車鍵,這是字符\n

會發生什麼),終於有東西可以閱讀stdin

getchar()不關心緩衝。它從stdin讀取,等到有些東西可以讀取。然後,它讀取單個字符,所以如果在stdin的輸入緩衝區更多的字符,他們將呆在那裏,直到通過getchar()任何其他功能stdin讀書讀。

+0

getch()僅僅是getchar()的包裝器,所以根據你的假設 - 每個getch()實際上都是一個getchar()這裏;) – macfij

+0

啊,現在看看,手動實現'ungetch )'......好的是緩衝發生在'stdio'流中,我希望這是OP的混亂之源:) –

相關問題