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)
{
    // ...
}

(コードがすべて 1 つのファイルにある場合、静的はほとんど無意味であることに注意してください。ただし、mygetchar をヘッダーと実装ファイルにプルする場合は、静的グローバルを使用して、リンク可能にならないようにする必要があります。同じコンパイル単位の外側。)

(楽しい事実: と0の はbufCurbufEnd実際には暗黙のままにすることができます。わかりやすくするために、それらを置きますが、標準では、ゼロで初期化する必要があると規定されています。


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 に答える