get_next_line 과제에서는 open, read, close에서 read만 허용을 하는 과제입니다.
read만 공부하고는 과제에 임하기 어렵다.
open, read, close를 전부 알아야한다.
open
참고 사이트
- 헤더: fcntl.h
- 형태: int open (const char *FILENAME, int FLAGS[, mode_t MODE])
- 인수
- char *FILENAME 대상 파일 이름
- int FLAGS 파일에 대한 열기 옵션
- [, mode_t MODE] O_CREAT 옵션 사용에 의해 파일이 생성될 때 지정되는 파일 접근 권한
- 반환
- int 0 < 파일 열기에 성공하면 파일 디스크립터의 양의 정수 값 반환
- -1 == 실패
파일을 open할 때는 용도에 따라 읽기 전용, 쓰기 전용 또는 읽기와 쓰기 모두 되는 옵션을 지정하여 열기 가능 모두 <fcntl.h>에 정의되어 있음.


open()함수 예제
예제
: text.txt라는 파일이 없으면 파일을 생성하고 파일에 "jaeyoonjung\n"을 쓰기함.
그러나 이미 파일이 있으면 프로그램 종료
O_WRONLY : 쓰기 전용으로 열기
O_CREAT : 해당 파일이 없으면 생성
O_EXCL : CREAT를 사용했을 때 파일이 이미 있어도 열기가 가능하여 쓰기를 하면 이전 내용이 사라진다.
0644 : 리눅스 chmod 파일 권한 생각하면 된다.
#include <stdio.h>
#include <string.h> // strlen()
#include <fcntl.h> // O_WRONLY | O_CREAT | O_EXCL, 0644
#include <unistd.h> // write(), close()
int main()
{
int fd;
char *temp = "jaeyoonjung\\n";
fd = open("./test.txt", O_WRONLY | O_CREAT | O_EXCL, 0644);
if (0 < fd)
{
write(fd, temp, strlen(temp));
close(fd);
}
else
printf( "파일 열기에 실패했습니다.\\n");
}

실행 결과


Read
- 헤더: unistd.h
- 형태: ssize_t read (int fd, void *buf, size_t nbytes)
- 인수
- int fd : 파일 디스크립터
- void *buf : 파일을 읽어 들일 버퍼
- size_t nbytes : 퍼버의 크기
- 반환
- ssize_t == -1 실패
- 0 == 정상적으로 반환실행되었다면 읽어들인 바이트 수
쉽게 정의해보자
read(fd, buff, BUFF_SIZE);
이렇게 있다고 가정하면
fd : 우리가 불러들인 파일의 fd값 즉 파일의 번호.
buff : 우리가 fd파일에서 BUFFER_SIZE만큼 읽은 것을 buff에 넣어주는 것.
BUFFER_SIZE : 우리가 얼마만큼 읽을 것인가.
read()함수 예제
test.txt 파일 : 아래와 같이 5바이트씩 문장 입력되어 있다.
abcde
jaeyo
joonp
arkyj
oohap

test.txt파일은 29바이트 뒤에 개행이 없기 때문에 30바이트가 아님.
#include <stdio.h>
#include <string.h> // strlen()
#include <fcntl.h> // open()
#include <unistd.h> // write(), close()
#define BUFF_SIZE 1024
int main()
{
char buff[BUFF_SIZE + 1];
int fd;
int count;
count = 1;
fd = open("./test.txt", O_RDONLY);
while (count)
{
count = read(fd, buff, BUFF_SIZE);
if (count == 0)
break ;
if (count == -1)
return (0);
buff[count] = '\\0';
}
printf("%s", buff);
close(fd);
}
코드에 대해서 하나씩 설명하면서 해보자.
1. BUFFER_SIZE + 1
- test파일은 29바이트 BUFFER_SIZE는 1024이기 때문에 read를 실행시키면 test 파일을 한 번에 읽을 수 있다. BUFFER_SIZE 1이 1바이트라고 생각하면 된다.
-
- 1은 무엇인가? 우리가 읽은 만큼 뒤에 ‘\0’을 붙여 넣어서 문자 끝을 알 수 있게 만들 것임.
2. open
test.txt 파일을 open으로 열었음
3. while(count)
count에는 1로 초기화 되었는데 read함수로 들어가게 되면 count에는 read가 읽은 수 만큼의 바이트가 들어온다. 즉 BUFFER_SIZE는 1024인데 test.txt파일은 29바이트 이기 때문에 한 번에 다 읽을 수 있었다. 그래서 count에는 29가 들어오게 된다.
count == 0
: 파일에서 읽을 것이 없다는 뜻
count == -1
: 파일을 읽을 때 오류가 생긴 것
이제 buff에 밑에 부분 텍스트가 들어있다.
abcde
jaeyo
joonp
arkyj
oohap
이것에 대해서 문자열의 끝을 알기 위해
buff[count] = '\\0';
을 넣어줌 count는 29이기 때문에 buff에 제일 마지막 인덱스를 가리킴.

만약 BUFFER_SIZE가 test.txt 크기 보다 작으면..?
test.txt 크기 만큼 while문을 돌리면 된다.
어떻게 접근을 하지?
: 아까 count를 사용한다.
위에서 작성한 나의 코드는 작아도 문제가 없다. while문으로 접근을 하였기 때문이다.
#include <stdio.h>
#include <string.h> // strlen()
#include <fcntl.h> // open()
#include <unistd.h> // write(), close()
#define BUFFER_SIZE 4
int main()
{
char buff[BUFFER_SIZE + 1];
int fd;
int count;
count = 1;
fd = open("./test.txt", O_RDONLY);
while (count)
{
count = read(fd, buff, BUFFER_SIZE);
if (count == 0)
break ;
if (count == -1)
return (0);
buff[count] = '\\0';
}
printf("%s", buff);
close(fd);
}
BUFFER_SIZE가 4이더라도 while문을 통해 test.txt 29바이트까지 끝까지 읽게 된다.
BUFFER_SIZE 보다 test.txt 더 큰 경우인데 잘못된 코드
test.txt
abcde
jaeyo
joonp
arkyj
oohap
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#define BUFFER_SIZE 4
int main()
{
char buff[BUFFER_SIZE + 1];
int fd;
fd = open( "./test.txt", O_RDONLY);
if (fd > 0)
{
read(fd, buff, BUFFER_SIZE);
puts(buff);
close(fd);
}
return 0;
}
BUFFER_SIZE 4이기 때문에 while이 없으면 4바이트 밖에 못 읽는다.

close
- 헤더: unistd.h
- 형태: int close(int fd)
- 인수
- int 파일 디스크립터
- 반환
- int 0 == 정상적으로 close 되었음
- -1 == close 실패
참고 블로그
C언어 파일 닫기 함수 close()
C함수 파일 닫기 close() open() 함수로 열기한 파일을 사용 중지합니다. open()함수는 fcntl.h 에 정의 되어 있지만 write(), read(), close()는 unistd.h에 정의 되어 있습니다. 헤더: unistd.h 형태: int close(int fd)
badayak.com
'42Seoul > get_next_line' 카테고리의 다른 글
6. Mandatory part, Bonus part source code (2) | 2023.04.08 |
---|---|
5. 운영체제에 따른 read (0) | 2023.04.08 |
4. 정적 변수(static) (0) | 2023.04.08 |
2. OPEN_MAX, 연결리스트 vs 배열 (2) | 2023.04.08 |
1. 파일 디스크립터(file Descriptors) (0) | 2023.04.08 |