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

'버퍼'도 전역 변수로 만들어야합니다. 그렇지 않으면 읽기 호출 당 최대 1023자를 읽고 쓰는 중입니다. 'mygetchar'에 대한 후속 호출은 쓰레기를 반환합니다. – Anthony

답변

1

버퍼를주의 깊게 생각하십시오. 함수 호출이 끝나면 버퍼는 어떻게됩니까? 그것은 사라집니다.

1024 개의 호출 중 1023 개에 대해 버퍼가 단위 화되고 오프셋이 무의미한 데이터를 가리키고 있음을 의미합니다.


은 기본적으로 당신은 너무 버퍼를 전역 변수가 필요합니다

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

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

(코드는 하나 개의 파일에 모든 경우에 정적이 거의 무의미합니다 당신이 당신의 mygetchar을 끌어한다면. 하지만 헤더와 구현 파일로, 같은 컴파일 단위 외부에서 연결 가능한되는 것을 유지하기 위해 정적 글로벌을 사용할 것)

(재미있는 사실 :. bufCurbufEnd 행위에 대한 0의 묵시적으로 남겨 둘 수 있습니다. 명확하게하기 위해, 나는 그것들을 넣을 것이지만, 그들은 0으로 초기화되어야한다고 standard dictates한다. 당신이 세계에 대한 필요가 없습니다 (즉 것이 어디 나도 몰라) 다른 버퍼를 사용하여 계획하지 않는 한 조나단 레플러으로


는 지적했다. 함수 내에서 정적 변수를 사용할 수 있습니다 :

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

글쎄, 실제로 한 번의 호출로 버퍼를 채우는 데 충분하다면 1024 번 호출 할 때마다 한 번씩 'read'를 호출합니다. 이후의 모든 호출은 초기화되지 않은 배열에 인덱스를 반환합니다. 왜냐하면'buffer'는 지역 변수이기 때문입니다. – Anthony

+0

@ anthony-arnold 아, 네 말이 맞아. 나는 그의 직책이 세계에 있다는 것을 알지 못했다 :). – Corbin

+3

3 개의 변수 모두 함수에서'정적'으로 만들 수 있습니다. 그것은 더 좋을 수도 있습니다. 다른 코드가 변수에 액세스하지 못하게합니다. –