2013-03-20 127 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