2013-03-20 30 views
1

我試圖在unistd.h中使用read()來實現getchar()函數。實現getchar與讀取

由於系統調用很昂貴,我希望儘可能少執行read()函數。

如果我使用「getchar」,它工作正常。但是,在這種情況下,「mygetchar」不起作用。

任何人都可以指出我在下面做錯了什麼?

#include <stdio.h> 
#include <unistd.h> 

#define BUF_SIZE 1024 

int startIndex; 
int endIndex; 

int mygetchar(void){ 
    char buffer[BUF_SIZE]; 
    startIndex=0; 
    endIndex=0; 
    if(startIndex == endIndex){ 
    int r; 
    r = read(0,buffer,BUF_SIZE); 
    startIndex=0; 
    endIndex=r; 
    } 
    return buffer[startIndex++]; 
} 


int main(){ 
    char c; 
    int i=0; 
    do{ 
    c = mygetchar(); 
    putchar(c); 
    i++; 
    } 
    while(c != EOF); 
    return 0; 
} 
+0

你需要使'buffer'成爲全局的。否則,您正在讀取並丟棄每個讀取調用最多1023個字符,並且後續調用'mygetchar'會返回垃圾。 – Anthony 2013-03-20 02:15:37

回答

1

仔細想想你的緩衝區。函數調用結束時緩衝區會發生什麼?它消失了。

這意味着對於1024個調用中的1023個,您的緩衝區是單位化的,並且您的偏移量指向無意義的數據。


基本上你需要一個全局變量緩衝區太大:

static char buf[BUF_SIZE]; 
static size_t bufCur = 0; 
static size_t bufEnd = 0; 

int mygetchar(void) 
{ 
    // ... 
} 

(請注意,靜態是非常沒有意義的,當你的代碼都在一個文件中。如果你要拉你mygetchar。成雖然頭和實現文件,你可能需要使用一個靜態全局,以從從同一個編譯單元的外聯保持)

(有趣的事實:在0 S表示bufCurbufEnd行爲ually可以被隱含。爲了清楚起見,我會把它們,但他們將被零初始化的standard dictates


喬納森萊弗勒指出,除非你打算使用緩衝的其他地方(我不知道這將是),沒有必要爲一個全球性的。你可以在函數內部使用一個靜態變量:

void mygetchar(void) 
{ 
    static buf[BUF_SIZE]; 
    static size_t bufCur = 0; 
    static size_t bufEnd = 0; 
    // ... 
} 
+2

那麼,他實際上每1024次調用一次就調用'read'(假設文件中有足夠的空間來填充緩衝區)。每個後續調用都將索引返回到未初始化的數組中,因爲'buffer'是一個局部變量。 – Anthony 2013-03-20 02:17:38

+0

@ anthony-arnold啊,你說得對。我沒有注意到他的職位是全球性的:)。 – Corbin 2013-03-20 02:18:37

+3

或者這三個變量都可以在函數中做成'static'。這可能會更好;它會阻止任何其他代碼訪問變量。 – 2013-03-20 02:27:30