gnl

jiwoo·2022년 3월 7일
0

get_next_line

gnl 코드구현 전 메모

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

#define	BUFFER_SIZE 42
// gcc -Wall -Wextra -Werror -D BUFFER_SIZE=42 <files>.c

typedef struct s_gnl_list
{
	int		gnl_fd;
	char	*buff; //read() 버퍼저장공간
    char	*buff_cur; //버퍼를 어디까지 읽었는지 커서 표시
	t_gnl_list *next;
} t_gnl_list ;

//static ->https://en.wikipedia.org/wiki/Static_variable

char	*get_next_line(int fd)
{
	static t_gnl_list gnl_head; 
	t_gnl_list *list;

	// now = 해당 fd의 버퍼 존재확인
	//		있으면 해당 버퍼 반환
	//		없다면 head 뒤에 새것 추가하여 만 해당 list 주소 반환
	//
	// 1) buff 에 내용물 있는지 확인 - 없다면 '2' 번으로 있다면 '3' 번으로
	// 2) now->buff = read(fd); fd 읽어서 buff에 저장
	//		읽은것이 EOF 혹은, fd 읽는 것에 실패시, NULL 리턴 (4-3으로)
	// 3) 기존이 읽은 index, 혹은 처음부터 ~ \n, EOF 혹은 끝까지 len 세기,
	//		그 구간 malloc 해서 기존 str 에 붙여 저장. str 이 없었다면 새로 할당하여 저장.
	//		+ 어디까지 읽었는지 혹은 끝까지 읽었는지 혹은 EOF로 끝났는지 저장
	// 4-1) 끝까지 일반 문자열일 경우 - '2' 번으로가 반복
	// 4-2) \n 이었을 경우 - 어디까지 읽었는지 저장 + buff_cur = NULL 로 초기화
	// 4-3) EOF 이었을 경우(+오류발생시) - fd해당 연결리스트 할당 해제 및 삭제 + 다른 리스트 연결 시켜두기
	//		앞의 리스트, 뒤의 리스트 합쳐서 저장,
	//
	// str 반환
}

...

Bonus 보너스

  • *_bonus[c\h] 별개의 파일로 제출
    정적변수는 한 개만 선언해 쓸 것
    ->연결 리스트의 헤더를 정적변수로 선언
    여러 파일디스크립터를 다룰 수 있을 것
    ->연결 리스트에 fd번호를 저장하여 gnl함수 호출시 찾아서 사용한다.

...

static 정적변수 란?

-정의
프로그램 번역 과정의 마지막 단계인 적재 시간에 기억 장소를 할당받는 변수. 전체 프로그램의 시작부터 종료까지를 생존 기간으로 하며 동일 기억 장소를 보유한다. 따라서 전역 변수들은 모두 정적 변수다. 함수 등 부트프로그램에서 선언된 정적 변수는 그 부프로그램에 재 진입할 때 이전 기억 장소를 보유하고 있어서 그 변수의 이전 값들을 그대로 가지고 있다. 이는 일반적으로 동적 기억 장소 할당을 하는 지역변수와 대조적이다. -네이버지식백과

  • 특징
    메모리의 data 영역에 저장이 된다. (전역변수도 data 영역에 저장된다)
    (일반 변수들은 함수 실행시 stack 영역에 저장이되고 함수 종료 시 삭제된다.)
    정적 변수 선언시 0으로 초기화 된다.
    정적 변수는 외부 참조가 불가능하다. (지역 정적 변수 일때) (전역변수와 다른점)

...

EOF

end of file , EOF 매크로는 <stdio.h>에 -1 로 설정되어 있다.
EOF 매크로는 gnl에서는 사용하지 않을 것, → gnl에서는 read 반환값이 0일 때를 읽어 처리한다.
CTRL+D = EOT 는 입력의 종료를 뜻한다. (end of transmission)
아스키코드로 0x0004
파일을 read, write를 할때 터미널에서 eof로 인식된다

https://en.wikipedia.org/wiki/End-of-Transmission_character#Meaning_in_Unix

표준출력, 표준입력, 리다이렉션

gnl 로 표준출력을 넘겨줬을 때 표준출력 1, 표준입력 0 과 같은 작동을 하는 이유는 무엇?
내가 문자를 입력하면 입력한 문자를 동시에 출력해주기 때문이지 않나; 생각보다 단순한 이유

  • 리다이렉션
//% a.out < test.txt

int main(void)
{
	char *str;

	while (1)
	{
		str = get_next_line(0);
		printf("%s\n", str);
		if (str == NULL)
			break;
	}
}

...

file 디스크립터 란? +관련함수

file descriptor

파일 디스크립터는 특정한 파일에 접근하기 위한 번호

0 표준입력, 1 표준출력, 2 표준에러

  • fd 관련 함수 사용법
    
    <fcntl.h>
    int open(const char *path, int oflag, ...);
    // int	fd;
    // fd = open ("./test.txt", O_RDONLY);
    // O_RDWR read&write
    // O_RDONLY read only
    // O_WRONLY write only
    // 더 많은 flags -> https://www.it-note.kr/19
    int close(int files);
    // close(fd);
    
    <sys/types.h> //??
    <sys/uio.h> //??
    
    <unistd.h>
    ssize_t read(int fildes, void *buf, size_t nbyte);
    //files → fd, 파일디스크립터 번호
    //buf → 읽어서 저장할 장소
    //nbyte → 몇 바이트 만큼 읽어올 것인지
    //return value
    //	0이 아닌 양수 = 정상작동
    //	0 = 파일의 끝 eof
    //	-1 = 오류 발생

0개의 댓글