2012-03-03 6 views
1

getchar()이 어떻게 구현되는지 궁금합니다. 다음과 같은 것이 있습니까? 이 방법은 1 바이트 만 읽는 것이 비효율적입니다. 그것은 약간의 버퍼링을 사용합니까? 표준 C 라이브러리에 대한 구현의 수를 고려getchar()은 어떻게 구현 되었습니까?

Pseudo code: 

int getchar(){ 

char buf[1]; 
int n = read(0,buf,1); 
if(n < 1) 
    printf("Read failed"); 

return buf[0]; 
} 
+1

'ungetc()'의 존재는 * some * kind의 버퍼링을 사용해야한다는 것을 확인해야합니다. –

+0

Google 검색을 사용하면 다양한 구현 방식을 볼 수 있습니다. –

답변

2

, 그것은 명확한 답을 제공하는 것은 불가능하지만, 가장 일반적인 같은 일반적인 지침을 따르도록 보인다.

getchar()은 표준 C 라이브러리의 스트림 인프라 스트럭처, 즉 FILE과 그 친숙한 기능을 사용합니다. 대부분의 최신 C 라이브러리 구현에서 파일 스트림은 버퍼 크기와 버퍼 크기가 일반적으로 setvbuf()을 통해 조정할 수있는 정도로 버퍼링됩니다. fopen()에 추가 옵션을 통해 - - 메모리 매핑을 통해 액세스 할 (즉 mmap())보다는 read()/write() 파일을 선택적으로 할 수있다

나는 적어도 하나의 경우 (glibc) 알고있다. scanf()과 같이 상위 수준 함수를 호출 할 때 문제가 발생하지 않도록하려면 은 이고, 동일한 버퍼링 구조를 사용하는 것은입니다.

프로파일 러의 정보가 없으면 사용으로 인한 성능 문제보다 getchar()을 사용하는 코드의 구조적 복잡성에 대해 더 걱정할 것입니다.

+1

'mmap'을 사용하여'FILE * '을 구현하는 것은 불가능합니다. glibc의'mmap' 지원은'fopen' 함수에 비표준 플래그를 넘기는 경우에만 사용되는 옵션입니다. 이는 맵이 생성 된 후에 파일 잘림이 더 이상 존재하지 않는 부분에 접근하려고 할 때'SIGBUS'를 초래할 것이기 때문입니다. –

+0

@R .. : 나는이 점에 대해 더 명확하게하기 위해 나의 대답을 편집했다 - 나는'SIGBUS' 문제에 부딪혔다. 나는 그 부분에 더주의를 기울여야 만했다 ... – thkala

+1

커널이 새로운' 'SIGBUS'대신에 대체 신호를 사용하기위한 mmap 플래그와,이 신호가 응용 프로그램이 아닌 사용자 공간 표준 라이브러리 구현에 사용되도록 예약 된 경우 (pthread에서 사용하는 내부 신호와 비슷 함) 'mmap'을 사용하여 stdio 버퍼를 안전하게 구현할 수 있습니다. 그러나 성능 향상이 가능하도록 만드는 모든 노력에 비해 성능상의 이점이 매우 실망 스럽습니다. –

0

매우 간단한 구현입니다.

int mygetchar(void) 
{ 
     static char buf[BUFSIZ]; 
     static char *bufp = buf; 
     static int i = 0; 

     if (i == 0) 
     { 
       i = read(0, buf, 1); 
       bufp = buf; 
     } 
     if (--i >= 0) 
     { 
       return *bufp++; 
     } 

     return EOF; 
}