본문 바로가기

42cursus

get_next_line - 초간단 정리 (42seoul)

0. 프로젝트 목표

- get_next_line 함수 작성

- 파일디스크립터에서 읽고 줄바꿈전까지 문자열을 만들어 리턴

- 그 과정에서 static변수를 사용하여 문제를 해결하기

 

 

 

1. C언어에서의 static 변수

1
2
3
4
5
6
7
8
9
10
11
12
13
static int s_number1 = 10;
 
void    increase(void)
{
    s_number1++;
}
 
void    foo(void)
{
    static int s_number2 = 5;
 
    s_number2++;
}
cs

-> 초기화는 컴파일 시에 한번만 초기화

-> 즉, 어떠한 값을 런타임이 아닌 컴파일 시에 알아야 함

-> 함수안에 있어도 지역변수처럼 스택메모리에 올라가는 것이 아닌 데이터영역에 올라감

-> C의 static은 파일접근범위임, 즉 다른 파일에서 static 키워드가 붙은 곳은 접근할 수 없음

-> 함수가 끝나고도 저장될 변수, 다른 파일에서 접근하지 못하게 할 경우 static을 붙임

-> get_next_line 에서는 줄바꿈 이후의 남은 버퍼들을 담는 공간으로 활용함

 

 

2. open함수의 fd에 따른 static변수 설정

1
2
3
4
5
6
7
8
9
#include <fcntl.h>
int open(path/filename, MODE);
 
int main(void)
{
    int fd;
    fd = open("test.txt", O_RDONLY);
    return (0);
}
cs

-> 해당 파일에 대한 정보(int형 정수)를 반환 받을 수 있음

-> 그 fd 값으로 read(fd, )나 write(fd, )하여 파일입출력을 가능하게 함 (물론 표준입출력도)

-> get_next_line 에서는 static을 활용하여 줄바꿈 이후의 버퍼를 설정하는 것으로 함

-> 근데 보너스에서 fd값에 따른 버퍼를 설정해야 하기 때문에

-> static char *rest[]로 설정함

-> 근데 배열이 정적으로 크기가 정해지면 동적할당 없이 fd에 따라 O(1)만에 접근할 수 있기 때문에

-> fd값의 최대 범위만 찾으면 됨

-> fd의 최대는 limits.h에 정의된 OPEN_MAX 상수임 (osx에서 10240, 슬랙검색이 최고인듯)

 

 

3. read 함수의 반환 값으로 판단하기

1
2
3
4
5
6
7
8
9
#include <unistd.h>
 
int read_size;
 
read_size = read(fd, buffer, BUFFER_SIZE);
 
if (read_size > 0)    return RET_SUCCESS;
if (read_size == 0)    return RET_EOF;
if (read_size < 0)    return RET_ERROR;
cs

-> read는 fd파일에서, 최대 BUFFER_SIZE 만큼 읽고 buffer에 담아 읽은 size 반환

-> 조심해야 하는 것은 read가 음수를 반환할 수 있기 때문에 꼭 sign으로 변수를 받아야 함 (size_t X)

-> read_size == 0 인 경우,  해당 파일에서 읽을 것이 없음을 알림 (set EOF)

-> read_size < 0 인 경우 (-1), open하지도 않은 fd를 읽을려 하거나, 예상치 못한 경우 음수를 반환

-> gnl에서 각각의 경우에 따른 처리를 해줘야 하기 때문에 로직을 잘짜야 함

 

 

4. 알고리즘 구현 요소

-> str관련 함수는 전에 짜본 str_util함수 쓰는 것이 읽기에도, 작성하기에도 편한 듯

-> 카피해서 만들고 싶으면 strdup()

-> 붙이고 싶으면 strcat or strcpy or strjoin

-> 문자하나 찾고 싶으면 strchr

-> 이런 식으로 작성하는 것이 편한 듯

 

-> 또한 char *rest에 동적할당하여 읽은 것을 붙여넣기를 했는데

-> rest의 의미가 깨진다고 생각하면 지역 변수하나 둬서 cat_buffer를 두어도 될듯

 

-> while() 문이나 조건문 이후에는 어떠한 경우가 완전히 배제된 상황을 꼭 주석으로 달아서 이용하기

-> 예를 들면 "while을 나오는 경우는 줄바꿈을 만났거나, EOF거나 ERROR구나.."

-> 라고 정하고 아래부분 작성하기

 

 

5. 매크로 상수 정의하기

컴파일 시에 매크로 상수를 변경하고 싶을 때 사용

1
2
3
4
5
#ifndef BUFFER_SIZE
    #define BUFFER_SIZE 1024
#endif
 
> gcc -D BUFFER_SIZE=2048 main.c
cs