핵심 정리

파일 열기

파일 읽기/쓰기를 하기 전에는 fopen 함수로 파일을 열어야 합니다. 파일 열기에 성공하면 파일 포인터(FILE *)를 반환하고, 실패하면 NULL을 반환합니다.

FILE *fp = fopen(파일명, 파일모드);    // 파일 열기

파일 닫기

파일 읽기/쓰기 작업이 끝났다면 반드시 fclose 함수로 파일 포인터를 닫아줍니다. 파일 포인터를 닫지 않으면 메모리 누수 현상이 발생합니다.

fclose(파일포인터);    // 파일 포인터 닫기

파일 모드

파일을 열 때는 용도에 따라 다양한 파일 모드를 지정해야 합니다.

파일 모드
파일 모드 기능 설명
"r" 읽기 전용 파일을 읽기 전용으로 엽니다. 단, 파일이 반드시 있어야 합니다.
"w" 쓰기 전용 새 파일을 생성합니다. 만약 파일이 있으면 내용을 덮어씁니다.
"a" 추가 파일을 열어 파일 끝에 값을 이어 씁니다. 만약 파일이 없으면 파일을 생성합니다.
"r+" 읽기/쓰기 파일을 읽기/쓰기용으로 엽니다. 단, 파일이 반드시 있어야 하며 파일이 없으면 NULL을 반환합니다.
"w+" 읽기/쓰기 파일을 읽기/쓰기용으로 엽니다. 파일이 없으면 파일을 생성하고, 파일이 있으면 내용을 덮어씁니다.
"a+" 추가(읽기/쓰기) 파일을 열어 파일 끝에 값을 이어 씁니다. 만약 파일이 없으면 파일을 생성합니다. 읽기는 파일의 모든 구간에서 가능하지만, 쓰기는 파일의 끝에서만 가능합니다.
t 텍스트 모드 파일을 읽거나 쓸 때 개행문자 \n\r\n을 서로 변환합니다. ^Z를 파일의 끝으로 인식하므로 ^Z까지만 파일을 읽습니다(^Z는 Ctrl+Z 입력을 뜻합니다).
b 바이너리 모드 파일의 내용을 그대로 읽고, 값을 그대로 씁니다.

서식을 지정하여 파일에 문자열 쓰기

fprintf 함수를 사용하면 서식을 지정하여 파일에 문자열을 쓸 수 있습니다.

// 서식을 지정하여 파일에 문자열 쓰기
fprintf(파일포인터, 서식, 1, 2, ...);

서식을 지정하여 파일에서 문자열 읽기

fscanf 함수를 사용하면 서식을 지정하여 파일에서 문자열을 읽을 수 있습니다.

// 서식을 지정하여 파일에서 문자열 읽기
fscanf(파일포인터, 서식, 변수의주소1, 변수의주소2, ...);

파일에 데이터 쓰기

fwrite 함수를 사용하면 파일에 데이터를 쓸 수 있습니다. 버퍼는 파일에 쓸 내용을 뜻하며 포인터(메모리 주소)를 넣어줍니다. fwrite 함수는 쓰기에 성공하면 성공한 쓰기 횟수가 반환됩니다. 여기서 성공은 쓰기 크기에 지정한 크기만큼 썼느냐를 기준으로 합니다.

// 파일에 데이터 쓰기
fwrite(버퍼, 쓰기크기, 쓰기횟수, 파일포인터);

파일에서 데이터 읽기

fread 함수를 사용하면 파일에서 데이터를 읽을 수 있습니다. 버퍼는 파일의 내용을 읽어서 저장할 공간을 뜻하며 포인터를 넣어줍니다. fread 함수는 읽기에 성공하면 성공한 읽기 횟수가 반환됩니다. 여기서 성공은 읽기 크기에 지정한 크기만큼 읽었느냐를 기준으로 합니다.

// 파일에서 데이터 읽기
fread(버퍼, 읽기크기, 읽기횟수, 파일포인터);

fread 함수로 파일에서 문자열이나 구조체를 읽을 때 반드시 버퍼를 0으로 초기화 해줍니다. 버퍼를 초기화하지 않으면 이전에 메모리에서 사용하던 값이 남아있게 됩니다. 따라서 NULL이 없어서 문자열의 끝을 찾을 수 없거나 구조체의 멤버에 의도치 않은 값이 들어갈 수 있으므로 주의해야 합니다.

파일에 문자열 쓰기

fputs, fwrite 함수를 사용하면 파일에 문자열을 쓸 수 있습니다. fwrite 함수를 사용하여 파일에 문자열을 쓸 때는 쓰기 크기에 문자열의 길이를 구해서 넣어줍니다.

// 파일에서 문자열 쓰기
fputs(문자배열, 파일포인터);
fputs(문자열포인터, 파일포인터);
fwrite(문자배열, strlen(문자배열), 1, 파일포인터);
fwrite(문자열포인터, strlen(문자열포인터), 1, 파일포인터);

파일에서 문자열 읽기

fgets, fread 함수를 사용하면 파일에서 문자열을 읽을 수 있습니다. fgets 함수는 지정된 버퍼 크기만큼 문자열을 읽습니다. 만약 파일에 \n이 있으면 \n까지 문자열을 읽습니다(\n도 포함).

// 파일에서 문자열 읽기
fgets(문자배열, 읽기크기, 파일포인터);
fgets(문자열포인터, 읽기크기, 파일포인터);
fread(문자배열, 읽기크기, 1, 파일포인터);
fread(문자열포인터, 읽기크기, 1, 파일포인터);

파일에 구조체 쓰기

파일에 구조체를 쓸 때는 쓰기 크기에 구조체의 크기를 구해서 넣어줍니다.

// 파일에서 구조체 쓰기
fwrite(&구조체변수, sizeof(struct 구조체), 1, 파일포인터);
fwrite(구조체포인터, sizeof(struct 구조체), 1, 파일포인터);

파일에서 구조체 읽기

파일에서 구조체를 읽을 때는 읽기 크기에 구조체의 크기를 구해서 넣어줍니다.

// 파일에서 구조체 읽기
fread(&구조체변수, sizeof(struct 구조체), 1, 파일포인터);
fread(구조체포인터, sizeof(struct 구조체), 1, 파일포인터);

파일 포인터의 위치 변경하기

fseek 함수는 파일 포인터를 이동시킵니다. 이후 파일 포인터를 사용하는 함수들은 파일 포인터가 위치한 부분부터 읽고 쓰게 됩니다.

fseek(파일포인터, 이동할크기, 기준점);
fseek 함수의 기준점 종류
기준점 설명
SEEK_SET 파일의 처음부터 이동을 시작 fseek(fp, 0, SEEK_SET); // 파일포인터를 파일의 처음으로 이동시킴
SEEK_CUR 현재 위치부터 이동을 시작 fseek(fp,-10, SEEK_CUR); // 파일 포인터를 현재 위치에서 10바이트만큼 역방향으로 이동시킴(-10)이 음수이므로
SEEK_END 파일의 끝부터 이동을 시작 fseek(fp, 0, SEEK_END);// 파일 포인터를 파일의 끝으로 이동시킴

특히 fread, fwrite 함수는 읽기/쓰기 크기와 횟수를 함께 지정하므로 파일 포인터도 읽고 쓴 크기 * 횟수만큼 전진하게 됩니다.

파일 포인터의 역방향,순방향 이동

파일의 끝 방향으로 이동하는 것을 순방향으로 이동(전진, forward)라고 하고, 파일의 처음 방향으로 이동하는 것을 역방향으로 이동(후진, forward)라고 합니다.

파일 포인터의 현재 위치 얻기

ftell 함수는 파일 포인터의 현재 위치(읽기/쓰기 위치)를 반환합니다.

long pos = ftell(파일포인터);

파일 포인터가 파일의 끝인지 검사하기

feof 함수를 사용하면 파일 포인터가 파일의 끝인지 검사할 수 있습니다. 파일 포인터가 끝이면 1을 반환하고 끝이 아니면 0을 반환합니다.

int eof = feof(파일포인터);

파일의 처음으로 되돌아가기

rewind 함수를 사용하면 파일 포인터를 파일의 처음으로 이동시킬 수 있습니다.

rewind(파일포인터);

파일의 크기 구하기

fseek 함수에 SEEK_END를 지정하여 파일 포인터를 파일의 끝으로 이동시킨 뒤 ftell 함수를 사용하면 파일의 크기를 구할 수 있습니다.

// 파일의 크기 구하기
fseek(fp, 0, SEEK_END);    // 파일 포인터를 파일의 끝으로 이동시킴
long size = ftell(fp);     // 파일 포인터의 현재 위치를 얻음