2016-07-18 3 views
0

처럼 readline() 기능을 구현하십시오. 나는 이것을 구현하려고 생각했다.readline()과 같이 한 줄씩 읽음 파일을 구현하려면

나는 먼저 read(fd, buf, 4096);과 같은 파일을 읽어야한다. 그런 다음 buf[i]if (buf[i] == '\n')과 같은 바이트로 비교해야한다.

해당하는 경우 i이 표시되면 lseek()을 사용하여 첫 번째 파일 오프셋으로 이동 한 다음 다시 read(fd, buf, i)을 입력하십시오. 이와 같이 fisrt 작업을 수행하면 두 번째 readline() 호출이이 메커니즘을 다시 수행합니다.

이 솔루션을 처음에는 생각했지만 buf[i]은 바이트 단위로 비교한다는 의미이므로 fd의 모든 문자를 읽으려면 너무 느립니다. 나는 이것 같이 비교해야 하는가 또는 더 나은 해결책 있는가 ??

+4

fget/fgets를 사용하지 않는 이유는 무엇입니까? – inzanez

+0

줄 단위로 읽습니다. 하지만 read()를 사용하여 솔루션을 알고 싶습니다. fgets 또는 다른 표준 I/O 함수는 결국 read(), write() 시스템 호출을 사용하기 때문에. – allen

+3

그냥 아이디어 :'readline' 소스 코드를 탐색하여 어떻게하는지 볼 수 있습니다. – Siguza

답변

-2

fgetc를 'read'를 사용하여 1 문자로 구현하고, 독자적인 getc를 사용하여 readline을 구현 하시겠습니까?

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <stdlib.h> 

char my_getc() 
{ 
    unsigned char ch[1]; 

    read(1, ch, 1); 

    return ch[0]; 

} 

char *my_readline() 
{ 
     char line[4096]; 
     char *ret; 
     char c; 
     int position = 0; 

     while(c = my_getc() != '\n') 
       line[position++] += c; 

     line[position] = '\0'; 

     ret = malloc(sizeof(char) * strlen(line)); 


     return ret; 
} 



int main(int argc, char *argv[]) 
{ 
     char c; 

     printf("%s\n", my_readline()); 

} 

당신은 어쩌면 기존의 구현의 소스를 읽어야 잘 테스트 솔루션을 필요로하는 경우

...

+0

1)'ret []'의 내용이 절대 설정되지 않습니다 - 코드가 작동하지 않습니다. 2) 버퍼 오버플로에 대한 보호가 없습니다. 3)'EOF'가 없습니다. 4) 할당 된 버퍼는 free가 아닙니다. – chux

3

난 당신이 fgets()을 사용할 수없는 이유는이에 운동 있다는 것을 가정하여 해요 POSIX 저수준 입출력 기능에 대해 배우고 버퍼링에 대해 조금 배우기로되어있다. 데이터를 얻는 데 정말로 신경을 쓰면 파일 설명자를 사용하여 fdopen()을 통해 스트림을 래핑 한 다음 fgets()을 사용하여 읽는 것이 좋습니다.

I는 처음에이 용액을 생각했지만, [i]는, 바이트 단위로 비교하는 수단은, 상기 FD에서 문자를 모두 읽을 너무 느린 buf를 비교. 나는 이것 같이 비교해야 하는가 또는 더 나은 해결책 있는가 ??

주어진 바이트의 첫 번째 모양까지 읽으 려합니다. 읽은 각 바이트를 검사하지 않고 어떻게 할 수 있다고 생각하십니까? 어쩌면 하드웨어 지원을 제외하고는 불가능합니다.

어쨌든 귀하의 우려가 잘못되었다고 생각합니다. 나중에 메모리에서 데이터를 검사하는 것보다 디스크에서 메모리로 데이터를 이동하는 것이 훨씬 더 많은 비용이 듭니다. 제안하는 낮은 수준에서 작업하고 좋은 성능을 원한다면 read() 기반 접근 방식에서와 같이 디스크에서 데이터를 적절하게 큰 덩어리로 읽어야합니다.

반면에 이면 데이터를 다시 읽지 않으려 고하므로 성능이 좋으면 lseek()은 적합하지 않습니다. 또한 파이프와 같이 탐색 할 수없는 파일을 처리해야하는 경우 lseek()은 완전히 문제가되지 않습니다. 두 경우 모두 버퍼를 어떻게 든 유지해야하며 내용에서 여러 요청을 처리 할 준비가되어 있어야합니다. 또한 라인 경계가 버퍼 경계와 일치하지 않을 수도 있고, 때때로 개행을 찾기 위해 둘 이상의 읽기가 필요할 수도 있고 라인이 버퍼보다 ​​길어질 수도 있다고 생각할 수 있어야합니다 그건.

따라서 fgets() 및 기타 스트림 기반 I/O 대안이 옵션이 아니면 해결할 버퍼 관리 문제가 있습니다. 거기서 시작하는 것이 좋습니다. 일단 문제가 해결되면 해당 버퍼링 측면에서 fgets()의 아날로그를 작성하는 것이 간단해야합니다.

관련 문제