1

我试图在 unistd.h 中使用 read() 实现 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;
}
4

1 回答 1

1

仔细考虑你的缓冲区。函数调用结束时缓冲区会发生什么?它消失了。

这意味着对于 1024 次调用中的 1023 次,您的缓冲区未初始化,并且您的偏移量指向无意义的数据。


基本上,您也需要缓冲区的全局变量:

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

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

(请注意,当您的代码都在一个文件中时,静态几乎毫无意义。如果您要将 mygetchar 拉到头文件和实现文件中,您将希望使用静态全局以防止它被链接在同一编译单元之外。)

(有趣的事实:0sbufCurbufEnd实际上可以隐含。为了清楚起见,我会放它们,但标准规定它们要进行零初始化。


正如 Jonathan Leffler 指出的那样,除非您计划在其他地方使用缓冲区(我不知道那会在哪里),否则不需要全局。您可以在函数内部使用静态变量:

void mygetchar(void)
{
    static buf[BUF_SIZE];
    static size_t bufCur = 0;
    static size_t bufEnd = 0;
    // ...
}
于 2013-03-20T02:15:10.123 回答