`fgets` 함수
fgets 함수 (fgets)
파일에서 한 줄씩 읽는 건 정말 자주 하는 일이에요. fgets는 그 작업을 버퍼 오버플로 걱정 없이 안전하게 해 주는 함수예요. 줄 단위가 아니라 "최대 몇 글자까지"라는 단위로 동작해서, 내가 준 버퍼 크기를 넘지 않는 선에서 읽도록 설계되어 있어요.
출처: cppreference
본문
함수 원형
<stdio.h>에 정의돼 있어요.
char* fgets( char* str, int count, FILE* stream ); // (until C99)
char* fgets( char* restrict str, int count, FILE* restrict stream ); // (since C99)
설명 (Explanation)
주어진 파일 스트림에서 최대 count - 1개의 문자를 읽어 str이 가리키는 문자 배열에 저장해요. 개행 문자를 만나면 그 지점에서 파싱을 멈추는데, 이때 str에는 그 개행 문자까지 포함돼요. 파일 끝(end-of-file)에 도달해도 멈춰요. 바이트가 읽히고 오류가 없다면, str에 마지막으로 쓰인 문자 바로 뒤에 널 문자('\0')를 기록해요.
매개변수 (Parameters)
str— char 배열의 한 요소를 가리키는 포인터count— 쓸 최대 문자 수(보통str의 길이)stream— 데이터를 읽어올 파일 스트림
반환값 (Return value)
성공하면 str을, 실패하면 널 포인터를 돌려줘요.
파일 끝 조건을 만난 경우 stream에 eof 표시를 설정해요(feof() 참고). 이때 아무 바이트도 읽지 못했다면 실패로 처리되어 널 포인터를 돌려주고, str이 가리키는 배열의 내용은 바뀌지 않아요(즉 첫 바이트가 널 문자로 덮이지 않아요).
다른 오류로 실패했다면 stream에 오류 표시를 설정해요(ferror() 참고). 이 경우 str이 가리키는 배열의 내용은 불확정(indeterminate)이에요(널 종료조차 안 되어 있을 수 있어요).
주의할 점 (Notes)
POSIX는 읽기 오류가 발생하면 fgets가 errno를 설정하도록 추가로 요구해요.
표준 명세가 count <= 1인 경우를 명확히 다루지 않아서 구현마다 다를 수 있는데, 흔한 구현은 이러합니다.
count < 1: 아무것도 하지 않고 오류로 보고count == 1: 어떤 구현은 아무것도 하지 않고 오류로 보고, 다른 구현은 아무것도 읽지 않고str[0]에 0을 저장한 뒤 성공으로 보고
예제 (Example)
임시 파일에 몇 줄을 써 두고, 작은 버퍼(char buf[8])로 옮겨 읽으면서 버퍼 크기만큼 잘려 나가는 모습을 보여 줘요.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE* tmpf = tmpfile();
fputs("Alan Turing\n", tmpf);
fputs("John von Neumann\n", tmpf);
fputs("Alonzo Church\n", tmpf);
rewind(tmpf);
char buf[8];
while (fgets(buf, sizeof buf, tmpf) != NULL)
printf("\"%s\"\n", buf);
if (feof(tmpf))
puts("End of file reached");
}
출력:
"Alan Tu"
"ring
"
"John vo"
"n Neuma"
"nn
"
"Alonzo "
"Church
"
End of file reached
버퍼가 8바이트라서 count - 1인 7글자씩 끊겨 읽히는 걸 볼 수 있어요. 마지막에 feof로 파일 끝까지 읽었는지 확인하는 게 이 함수 사용의 정석이에요.
같이 보기 (See also)
scanf/fscanf/sscanf— 서식 입력fputs— 파일 스트림에 문자열 쓰기