파일 처리 함수 - 2
순차파일 입출력함수와 랜덤파일 입출력함수, 랜덤파일의 위치제어.
- 학습 목표
- 순차파일을 만들고 읽기.
- 랜덤파일 만들고 읽기.
- 랜덤파일의 위치 제어.
주요 용어
- 레코드(record) : 파일을 구성하는 논리적인 기본 단위.
- 텍스트 모드(textmode) : \n과 CR/LF 사이의 변환과정을 거치는 파일 모드.
- 2진 모드(binary mode) : \n과 CR/LF 사이의 변환과정 없는 파일 모드.
- 랜덤파일의 위치제어 : fseek()를 사용하여 랜덤파일의 특정부분을 입출력하는 것..
순차파일 입출력 함수
순차파일 출력함수
만들어진 파일에 자료를 기록하는 함수.
- putc(), fputc(), fputs(), fprintf()
putc()
- 문자 단위의 파일 출력함수.
- fputc()와 유사.
- 형식 : putc(문자변수, 파일포인터변수);
- 사용 예 : putc(c, fp);
- 기능 : fp가 가리키는 파일에 변수 c에 있는 문자 출력.
#include <stdio.h>
#include <stdlib.h>
void main()
{
// 파일 포인터 선언
FILE *fp;
char c;
// 파일 생성이므로 텍스트 쓰기모드로 오픈.
fp = fopen("putc.tt.txt", "w");
// 파일 개방 여부 체크. -> 에러메세지와 프로그램 종료.
if (fp == NULL)
{
printf("FAIL TO OPEN FILE");
exit(1);
}
// 문자 출력의 끝 확인.
while ((c = getchar()) != EOF)
{
// 문자를 파일로 출력.
putc(c, fp);
}
printf("END OF WHILE!");
fclose(fp);
}
fputs()
- 문자열을 파일로 출력.
- 형식 : fputs(문자열변수, 파일포인터변수);
- 사용 예 : fputs(s, fp);
- 기능 : 지정된 파일에 문자열(하나의 레코드) 출력.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main() {
char name[64];
FILE *fp;
// 텍스트 쓰기모드 개방하고, 에러시 프로그램 종료.
if ((fp = fopen("02_fputs.tt.txt", "w")) == NULL) {
puts("CAN NOT OPEN FILE");
exit(1);
}
gets(name);
while (strcmp(name, "end")) {
// 하나의 문자열에 개행문자 추가.
strcat(name, "\n");
// 문자열을 fp가 가르키는 파일에 수록.
fputs(name, fp);
gets(name);
}
printf("BYE!\n");
// 파일 닫기.
fclose(fp);
}
fprintf()
- 지정된 형식을 가지로 파일에 자료를 출력.
- 여러 항목의 복합적인 자료로 구성된 레코드를 저장할 때 유용.
- 형식 : fprintf(파일포인터변수, "출력형식", 변수);
- 사용 예 : fprintf(fp, "%s %d\n", a, b);
- 기능 : 지정된 형식대로 자료를 파일포인터 변수가 가리키는 곳에 출력.
#include <stdio.h>
#include <stdlib.h>
void main()
{
FILE *fp;
char no[10], name[10];
int mid, term, rep, att, i;
if ((fp = fopen("03_fprintf.tt.txt", "w")) == NULL)
{
puts("CAN NOT OPEN FILE");
exit(1);
}
// stdout : 모니터를 가리키는 특수한 파일포인터.
fprintf(stdout, "insert no name mid term rep att.");
for (i = 0; i < 5; ++i)
{
scanf("%s %s %d %d %d %d", no, name, &mid, &term, &rep, &att);
// 지정된 형식으로 자료를 파일에 출력.
fprintf(fp, "%10s %8s %3d %3d %3d %3d\n", no, name, mid, term, rep, att);
}
printf("BYE!\n");
// 파일 닫기.
fclose(fp);
}
C 언어에서 입출력 장치를 파일 개념으로 처리
- 자동적으로 3개의 표준 파일에 대한 포인터를 생성함.
- 이러한 표준 파일에 대해서는 다로 파일포인터를 선언할 필요가 없음.
표준파일 | 파일 포인터 | 대응 장치 |
---|---|---|
입력 | stdin | 키보드 |
출력 | stdout | 모니터 |
에러 | stderr | 모니터 |
순차파일 입력함수
파일 출력함수에 의해 만들어진 순차파일의 저장된 자료를 읽어내는 함수.
자료를 읽을 때는 파일의 끝에 있는 EOF 신호를 만날 때까지 읽을 수 있는 프로그램 작성.
- getc(), fgetc(), fgets(), fscanf()
getc()
- 문자 단위의 파일 입력함수.
- fgetc() 함수와 유사.
- 형식 : getc(파일포인터변수);
- 사용예 : c = getc(fp);
- 기능 : 지정된 파일로부터 한 문자를 읽어온다.
#include <stdio.h>
#include <stdlib.h>
void main() {
FILE *fp;
char c;
if ((fp = fopen("01_putc.tt.txt", "r")) == NULL) {
puts("\n\nCAN NOT OPEN FILE");
exit(1);
}
while ((c = getc(fp)) != EOF) {
putchar(c);
}
printf("\n\nBYE!\n");
// 파일 닫기.
fclose(fp);
}
fgets()
- 파일에 저장된 문자열 자료를 읽을 때 사용.
- 읽어 낼 문자열의 길이를 반드시 명시.
- 형식 : fget(문자열변수, 문자열 길이 + 1, 파일포인터 편수);
- 사용 예 : fget(s, 40, fp);
- 기능 : 지정된 파일로부터 해당 문자열 길이 만큼의 문자를 읽어 문자열 변수에 저장한다.
#include <stdio.h>
#include <stdlib.h>
void main() {
char name[20];
FILE *fp;
if ((fp = fopen("02_fputs.tt.txt", "r")) == NULL) {
puts("\n\nCAN NOT OPEN FILE");
exit(1);
}
// 파일의 끝에 도달할 때까지 읽기.
while (fgets(name, 20, fp) != NULL) {
printf("%s", name);
}
printf("\n\nBYE!\n");
// 파일 닫기.
fclose(fp);
}
scanf()
- 숫자, 문자 등 복합적인 자료로 구성된 레코드를 읽을 때 사용.
- 일반적으로 파일의 끝을 판별하는 feof()와 같이 사용.
- 형식 : fscanf(파일포인터변수, "입력형식", 변수);
- 사용 예 : fscanf(sp, "%s %d", &a, &b);
- 기능 : 파일 포인터가 가리키는 곳으로부터 지정된 형식대로 자료를 읽어온다.
#include <stdio.h>
#include <stdlib.h>
void main() {
FILE *fp;
char no[10], name[10];
int mid, term, rep, att;
if ((fp = fopen("03_fprintf.tt.txt", "r")) == NULL) {
puts("\n\nCAN NOT OPEN FILE");
exit(1);
}
printf("no name mid, term, rep, att\n");
// 파일의 끝인지 확인하는 feof()
while (!feof(fp)) {
// 파일에 저장된 자료의 형식에 맞게 입력형식을 지정해야 함.
fscanf(fp, "%10s %8s %3d %3d %3d %3d\n", no, name, &mid, &term, &rep, &att);
printf("%-10s %-8s %4d %4d %4d %4d\n", no, name, mid, term, rep, att);
}
printf("\n\nBYE!\n");
// 파일 닫기.
fclose(fp);
}
레코드 추가를 위한 사용 모드
a a+ ab ab+
- 형식 : fp = fopen("파일명", "a");
- 사용 예 : fp = fopen("파일명", "a");
- 기능 : 이미 만들어진 순차파일의 끝에 새로운 레코드 추가(append).
#include <stdio.h>
void main() {
FILE *fp;
// 레코드 추가 모드로 파일 개방.
fp = fopen("04_tt.dat", "a");
// 파일이 없으르모 새 파일 생성 후 새 내용 기록.
fputs("asdf \n", fp);
fputs("qwer \n", fp);
fputs("zxcv \n", fp);
fputs("qaz \n", fp);
fputs("wsx \n", fp);
fclose(fp);
}
랜덤파일 처리 (random file)
-
파일의 임의의 위치에서 자료를 읽거나 쓸 수 있음.
-
레코드의 길이가 일정함.
-
순차파일에 비해
- 장점 : 레코드 탐색이 빠르고 효과적.
- 단점 : 기억공간 낭비.
랜덤파일 열기
일반적으로 랜덤파일을 입출력할 때는 2진 모드로 파일을 개방.
- 2진 모드의 특징
- 텍스트 파일보다 적은 기억공간.
- 레코드의 길이를 개발자가 결정.
- 파일 포인터의 위치 변경 가능.
랜덤파일 입출력 함수
fwrite()
- 레코드의 길이를 지정.
- 자료저장 변수는 포인터 형.
- 형식 : fwirte(저장자료변수, 레코드길이, 레코드개수, 파일포인터);
- 사용 예 : fwrite(name, 10, 1, fp);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
FILE *fp;
char name[10];
// 2진 파일 쓰기 모드 개방.
if ((fp = fopen("08_fwrite.dat", "wb")) == NULL)
{
puts("\n\nCAN NOT OPEN FILE");
exit(1);
}
gets(name);
while (strcmp(name, "END"))
{
// 2진 파일 쓰기.
fwrite(name, 10, 1, fp);
gets(name);
}
fclose(fp);
}
fread()
- 읽기에 성공하면 읽은 레코드 수를 리턴.
- 형식 : fread(읽을자료변수, 레코드길이, 레코드개수, 파일포인터);
- ex : fread(name, 10, 2, fp);
#include <stdio.h>
#include <stdlib.h>
void main() {
FILE *fp;
char name[10];
// 2진 파일 읽기 모드 개방.
if ((fp = fopen("08_fwrite.dat", "rb")) == NULL) {
puts("\n\nCAN NOT OPEN FILE");
exit(1);
}
while (1) {
// 레코드의 개수가 1이 아닌 값이 리턴되면 파일은 끝난다.
if (fread(name, 10, 1, fp) != 1)
break;
puts(name);
}
fclose(fp);
}
랜덤파일 위치 제어
레코드의 길이가 일정하기 때문에, 자료의 위치를 제어할 수 있음.
fseek()
- 파일 포인터를 임의의 위치로 이동시키는 함수.
- 랜덤파일의 특정부분을 입출력 할 수 있음.
- 형식 : fseek(파일포인터_변수, 이동할_상대위치, 기준위치를_지정하는*모드);
- ex : fseek( fp, 2 * REC_size, SEEK_SET );
기준위치 지정모드
stdio.h에 정의됨
기준위치모드 | 동일기호 | 설명 |
---|---|---|
0 | SEEK_SET | 파일의 시작위치 |
1 | SEEK_CUR | 현재 파일포인터의 위치 |
2 | SEEK_END | 파일의 끝 위치 |
#include <stdio.h>
#include <string.h>
void main()
{
char str[10];
FILE *fp = fopen("sample6.txt", "wt");
fputs("1234567890", fp);
fclose(fp);
fp = fopen("sample6.txt", "rt");
fseek(fp, 7, SEEK_SET);
fgets(str, 4, fp);
printf("print 3 str from 7 : %s\n", str);
// 890
fseek(fp, -2, SEEK_CUR);
fgets(str, 3, fp);
printf("print 2 char before 2 char cur loc : %s\n", str);
// 90
fseek(fp, -9, SEEK_END);
fgets(str, 6, fp);
printf("print 5 str from 9 char before last : %s\n", str);
// 23456
fclose(fp);
}
728x90
반응형
'Language > C' 카테고리의 다른 글
[C] 메모리 동적 할당 (0) | 2021.01.03 |
---|---|
[C] 파일 처리 함수 - 1 (0) | 2021.01.01 |
[C] 구조체와 공용체 - 2 (0) | 2021.01.01 |
[C] 구조체와 공용체 -1 (0) | 2020.12.27 |
[C] 배열과 포인터 - 3 (0) | 2020.12.27 |